﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Windows.Forms;
using HML.Design;

namespace HML
{
    /// <summary>
    /// 日期输入框控件
    /// </summary>
    [Description("日期输入框控件")]
    [DefaultProperty("DatePicker")]
    [TypeConverter(typeof(PropertyOrderConverter))]
    [Designer(typeof(DateInputDesigner))]
    [ToolboxItem(true)]
    [ToolboxBitmap(typeof(DateInput), "Controls.DateInput.Resources.DateInput.bmp")]
    public class DateInput : DpiControl, ISkinObject
    {
        #region 主题

        private SkinObjectXmlMetadata skinObjectXmlMetadata = null;
        /// <summary>
        /// 主题对象在主题文件信息
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual SkinObjectXmlMetadata SkinObjectXmlMetadata
        {
            get
            {
                if (this.skinObjectXmlMetadata == null)
                    this.skinObjectXmlMetadata = new SkinObjectXmlMetadata(Assembly.GetAssembly(typeof(DateInput)).GetName().Name, typeof(DateInput).Name);

                return this.skinObjectXmlMetadata;
            }
        }

        private SkinController skinController = null;
        /// <summary>
        /// 主题控制器
        /// </summary>
        [Description("主题控制器")]
        [Category("杂项")]
        [PropertyOrder(-360)]
        [DefaultValue(null)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinController SkinController
        {
            get { return this.skinController; }
            set
            {
                if (this.skinController == value)
                    return;

                if (this.skinController != null)
                    this.skinController.RemoveSkinObject(this);

                this.skinController = value;

                if (this.skinController != null)
                    this.skinController.AddSkinObject(this);
            }
        }

        private SkinEnabledState skinEnabled = SkinEnabledState.Auto;
        /// <summary>
        /// 主题是否启用
        /// </summary>
        [Description("主题是否启用")]
        [Category("杂项")]
        [PropertyOrder(-300)]
        [DefaultValue(SkinEnabledState.Auto)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinEnabledState SkinEnabled
        {
            get { return this.skinEnabled; }
            set
            {
                if (this.skinEnabled == value)
                    return;

                this.skinEnabled = value;
                this.OnSkinChanged();
            }
        }

        private SkinStyle skinStyle = SkinStyle.Normal;
        /// <summary>
        /// 主题风格
        /// </summary>
        [Description("主题风格")]
        [Category("杂项")]
        [PropertyOrder(-260)]
        [DefaultValue(SkinStyle.Normal)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinStyle SkinStyle
        {
            get { return this.skinStyle; }
            set
            {
                if (this.skinStyle == value)
                    return;

                this.skinStyle = value;
                this.OnSkinChanged();
            }
        }

        private StyleAppearanceObject stateAppearance;
        /// <summary>
        /// 风格外观
        /// </summary>
        [Description("风格外观")]
        [Category("杂项")]
        [PropertyOrder(-200)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public StyleAppearanceObject StyleAppearance
        {
            get
            {
                if (this.stateAppearance == null)
                    this.stateAppearance = new StyleAppearanceObject(this, null);
                return this.stateAppearance;
            }
        }

        /// <summary>
        /// 主题已更改
        /// </summary>
        public virtual void OnSkinChanged()
        {
            SkinManager.SyncSkinValueToProperty(this);
            this.Invalidate();

            if (this.datePicker != null)
            {
                this.datePicker.OnSkinChanged();
            }
        }

        private ISkinObject followSkinObject = null;
        /// <summary>
        /// 主题设置跟随指定主题对象（自己的设置不再生效，提供给代码使用）
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Localizable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual ISkinObject FollowSkinObject
        {
            get { return this.followSkinObject; }
            set
            {
                if (this.followSkinObject == value)
                    return;

                this.followSkinObject = value;
                this.OnSkinChanged();
            }
        }

        public virtual bool GetSkinObjectSkinStateCore()
        {
            return SkinManager.GetSkinObjectSkinState(this.FollowSkinObject ?? this);
        }

        void ISkinObject.InitializeInvalidate()
        {
            throw new NotImplementedException();
        }

        void ISkinObject.Invalidate()
        {
            this.Invalidate();
        }

        #endregion

        #region 停用事件

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler PaddingChanged
        {
            add { base.PaddingChanged += value; }
            remove { base.PaddingChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler TextChanged
        {
            add { base.TextChanged += value; }
            remove { base.TextChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler RightToLeftChanged
        {
            add { base.RightToLeftChanged += value; }
            remove { base.RightToLeftChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ImeModeChanged
        {
            add { base.ImeModeChanged += value; }
            remove { base.ImeModeChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageLayoutChanged
        {
            add { base.BackgroundImageLayoutChanged += value; }
            remove { base.BackgroundImageLayoutChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackColorChanged
        {
            add { base.BackColorChanged += value; }
            remove { base.BackColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ForeColorChanged
        {
            add { base.ForeColorChanged += value; }
            remove { base.ForeColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler Click
        {
            add { base.Click += value; }
            remove { base.Click -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler DoubleClick
        {
            add { base.DoubleClick += value; }
            remove { base.DoubleClick -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseClick
        {
            add { base.MouseClick += value; }
            remove { base.MouseClick -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseDoubleClick
        {
            add { base.MouseDoubleClick += value; }
            remove { base.MouseDoubleClick -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageChanged
        {
            add { base.BackgroundImageChanged += value; }
            remove { base.BackgroundImageChanged -= value; }
        }

        #endregion

        #region 新增属性

        private ContentObject content;
        /// <summary>
        /// 内容区
        /// </summary>
        [Description("内容区")]
        [Category("杂项")]
        [PropertyOrder(-194)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ContentObject Content
        {
            get
            {
                if (this.content == null)
                    this.content = new ContentObject(this);
                return this.content;
            }
        }

        private ClearButtonObject clearButton;
        /// <summary>
        /// 清除按钮
        /// </summary>
        [Description("清除按钮")]
        [Category("杂项")]
        [PropertyOrder(-182)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ClearButtonObject ClearButton
        {
            get
            {
                if (this.clearButton == null)
                    this.clearButton = new ClearButtonObject(this);
                return this.clearButton;
            }
        }

        private IconObject icon;
        /// <summary>
        /// 图标
        /// </summary>
        [Description("图标")]
        [Category("杂项")]
        [PropertyOrder(-180)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public IconObject Icon
        {
            get
            {
                if (this.icon == null)
                    this.icon = new IconObject(this);
                return this.icon;
            }
        }

        private DatePicker datePicker = null;
        /// <summary>
        /// 日期选择面板
        /// </summary>
        [Description("日期选择面板")]
        [Category("杂项")]
        [PropertyOrder(-158)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public DatePicker DatePicker
        {
            get
            {
                if (this.datePicker == null)
                    this.datePicker = new DatePicker() { FollowSkinObject = this };
                return this.datePicker;
            }
            set
            {
                this.datePicker = value;
            }
        }

        private bool readOnly = false;
        /// <summary>
        /// 是否只读
        /// </summary>
        [Description("是否只读")]
        [Category("杂项")]
        [PropertyOrder(-156)]
        [DefaultValue(false)]
        public bool ReadOnly
        {
            get { return this.readOnly; }
            set
            {
                if (this.readOnly == value)
                    return;

                this.readOnly = value;
                IContainerControl c = this.Parent.GetContainerControl();
                if (c != null)
                {
                    ((Control)c).SelectNextControl(this, true, true, true, true);
                }
                this.VaildUnSelectedValue(this.dateBody.selectElementItem);
                this.dateBody.selectElementItem = DateContentSelectedTypes.None;
                this.Invalidate();
            }
        }

        private DateInputOperateModes operateMode = DateInputOperateModes.Editor;
        /// <summary>
        /// 日期操作模式
        /// </summary>
        [Description("日期操作模式")]
        [Category("杂项")]
        [PropertyOrder(-154)]
        [DefaultValue(DateInputOperateModes.Editor)]
        public DateInputOperateModes OperateMode
        {
            get { return this.operateMode; }
            set
            {
                if (this.operateMode == value)
                    return;

                this.operateMode = value;
                this.VaildUnSelectedValue(this.dateBody.selectElementItem);
                this.dateBody.selectElementItem = DateContentSelectedTypes.None;
                this.Invalidate();
            }
        }

        #endregion

        #region 重写属性

        protected override Size DefaultSize
        {
            get { return new Size(138, 22); }
        }

        protected override ImeMode DefaultImeMode
        {
            get { return ImeMode.Off; }
        }

        public new Font Font
        {
            get { return base.Font; }
            set
            {
                if (base.Font == value)
                    return;

                base.Font = value;
                this.Height = this.GetControlAutoHeight();
                this.CalculationDateBodyElementSize();
            }
        }

        #endregion

        #region 停用属性

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new Padding Padding
        {
            get { return base.Padding; }
            set { base.Padding = value; }
        }

        [Bindable(false)]
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override string Text
        {
            get { return base.Text; }
            set { base.Text = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override RightToLeft RightToLeft
        {
            get { return base.RightToLeft; }
            set { base.RightToLeft = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new ImeMode ImeMode
        {
            get { return base.ImeMode; }
            set { base.ImeMode = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Image BackgroundImage
        {
            get { return base.BackgroundImage; }
            set { base.BackgroundImage = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override ImageLayout BackgroundImageLayout
        {
            get { return base.BackgroundImageLayout; }
            set { base.BackgroundImageLayout = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color BackColor
        {
            get { return this.StyleAppearance.Normal.BackColor; }
            set { }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color ForeColor
        {
            get { return this.StyleAppearance.Normal.TextColor; }
            set { }
        }

        #endregion

        #region 字段

        /// <summary>
        /// 当前鼠标按下的功能区
        /// </summary>
        private MouseDownAreaTypes mouseDownAreaType = MouseDownAreaTypes.None;
        /// <summary>
        /// 时间文本与图片的间距
        /// </summary>
        private int image_value_space = 2;
        /// <summary>
        /// 存放生成禁用状态图片
        /// </summary>
        private Image disable_image_tmp = null;
        /// <summary>
        /// 存放时间元素信息
        /// </summary>
        private DateBodyClass dateBody = new DateBodyClass();
        /// <summary>
        /// 日期面板显示状态
        /// </summary>
        private bool datePickerDisplayStatus = false;

        /// <summary>
        /// 边框厚度
        /// </summary>
        private int borderThickness = 1;

        /// <summary>
        /// 日期控件内容允许选中的元素(已排好序)
        /// </summary>
        List<DateContentSelectedTypes> dateBodyElements = new List<DateContentSelectedTypes>();

        private ToolStripDropDown tsdd = null;

        private ToolStripControlHost tsch = null;

        #endregion

        public DateInput()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.StandardClick, false);//自定义单击事件逻辑
            SetStyle(ControlStyles.StandardDoubleClick, false);//停用双加事件

            this.SuspendLayout();
            this.DatePicker.BorderVisible = true;
            this.DatePicker.BottomBarClearClick += this.datePicker_BottomBarClearClick;
            this.DatePicker.BottomBarNowClick += this.DatePicker_BottomBarNowClick;
            this.DatePicker.BottomBarConfirmClick += this.datePicker_BottomBarConfirmClick;
            this.DatePicker.DateValueChanged += this.DatePicker_DateValueChanged;
            this.DatePicker.DateFormatChanged += this.DatePicker_DateFormatChanged;
            this.UpdateDateBodyElements();
            this.SetDatePickerDateValueToText();
            this.UpdateDateSymbol();
            this.OnSkinChanged();
            this.ResumeLayout();

        }

        #region 重写

        protected override void OnScaleDpiChangedInitialize()
        {
            this.InitializeElement();
            this.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;

            Color border_color = this.Enabled ? this.StyleAppearance.Normal.BorderColor : this.StyleAppearance.Disabled.BorderColor;
            Color back_color = this.Enabled ? this.StyleAppearance.Normal.BackColor : this.StyleAppearance.Disabled.BackColor;

            // 背景
            SolidBrush back_sb = new SolidBrush(back_color);
            g.FillRectangle(back_sb, this.ClientRectangle);
            back_sb.Dispose();

            Region source_c_region = g.Clip;
            Region content_region = new Region(this.dateBody.content_rect);
            g.Clip = content_region;

            // 图片
            Image image = (this.Icon.Image != null) ? this.Icon.Image : HML.DateInput_Resources.DateInput_date_ico;
            if (this.Enabled)
            {
                g.DrawImage(image, this.dateBody.image_rect);
            }
            else
            {
                if (this.disable_image_tmp == null)
                {
                    this.disable_image_tmp = ControlHelper.CreateDisabledImage(image);
                }
                g.DrawImage(disable_image_tmp, this.dateBody.image_rect);
            }

            //文本
            if (this.DatePicker.DateValue.HasValue)
            {
                Region value_region = new Region(this.dateBody.value_rect);
                g.Clip = value_region;

                //日期高亮背景色
                if (this.Enabled && !(this.OperateMode == DateInputOperateModes.DropDown || this.dateBody.selectElementItem == DateContentSelectedTypes.None || this.dateBody.selectElementItem == DateContentSelectedTypes.Image || this.dateBody.selectElementItem == DateContentSelectedTypes.ClearButton))
                {
                    RectangleF highlight_rect = RectangleF.Empty;
                    switch (this.dateBody.selectElementItem)
                    {
                        case DateContentSelectedTypes.Year:
                            {
                                highlight_rect = this.dateBody.year_rect;
                                break;
                            }
                        case DateContentSelectedTypes.Month:
                            {
                                highlight_rect = this.dateBody.month_rect;
                                break;
                            }
                        case DateContentSelectedTypes.Day:
                            {
                                highlight_rect = this.dateBody.day_rect;
                                break;
                            }
                        case DateContentSelectedTypes.Hour:
                            {
                                highlight_rect = this.dateBody.hour_rect;
                                break;
                            }
                        case DateContentSelectedTypes.Minute:
                            {
                                highlight_rect = this.dateBody.minute_rect;
                                break;
                            }
                        case DateContentSelectedTypes.Second:
                            {
                                highlight_rect = this.dateBody.second_rect;
                                break;
                            }
                    }
                    if (this.Focused && highlight_rect != RectangleF.Empty)
                    {
                        SolidBrush highlight_back_sb = new SolidBrush(this.StyleAppearance.HighlightBackColor);
                        g.FillRectangle(highlight_back_sb, highlight_rect);
                        highlight_back_sb.Dispose();
                    }
                }


                SolidBrush text_nohighlight_sb = new SolidBrush(this.Enabled ? this.StyleAppearance.Normal.TextColor : this.StyleAppearance.Disabled.TextColor);
                SolidBrush text_highlight_sb = new SolidBrush(this.StyleAppearance.HighlightTextColor);
                SolidBrush symbol_sb = new SolidBrush(this.Enabled ? this.StyleAppearance.Normal.SymbolColor : this.StyleAppearance.Disabled.TextColor);
                StringFormat text_ft = (StringFormat)StringFormat.GenericTypographic.Clone();
                text_ft.Alignment = StringAlignment.Far;
                text_ft.LineAlignment = StringAlignment.Center;


                if (this.IsContainDateEmbody(DateEmbody.Year))
                {
                    g.DrawString(this.dateBody.year_str, this.Font, ((this.dateBody.selectElementItem == DateContentSelectedTypes.Year && this.Focused) ? text_highlight_sb : text_nohighlight_sb), this.dateBody.year_rect, text_ft);
                    if (this.Content.SymbolPattern == DateInputSymbolPattern.Unit)
                    {
                        TextRenderer.DrawText(g, this.dateBody.year_unit_str, this.Font, this.dateBody.year_unit_rect, this.Enabled ? this.StyleAppearance.Normal.SymbolColor : this.StyleAppearance.Disabled.TextColor, TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter | TextFormatFlags.PreserveGraphicsClipping);
                    }
                }
                if (this.IsContainDateEmbody(DateEmbody.Month))
                {
                    g.DrawString(this.dateBody.month_str, this.Font, ((this.dateBody.selectElementItem == DateContentSelectedTypes.Month && this.Focused) ? text_highlight_sb : text_nohighlight_sb), this.dateBody.month_rect, text_ft);
                    if (this.Content.SymbolPattern == DateInputSymbolPattern.Unit)
                    {
                        TextRenderer.DrawText(g, this.dateBody.month_unit_str, this.Font, this.dateBody.month_unit_rect, this.Enabled ? this.StyleAppearance.Normal.SymbolColor : this.StyleAppearance.Disabled.TextColor, TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter | TextFormatFlags.PreserveGraphicsClipping);
                    }
                    else
                    {
                        g.DrawString(this.dateBody.yearmonth_str, this.Font, symbol_sb, this.dateBody.yearmonth_rect, StringFormat.GenericTypographic);
                    }
                }
                if (this.IsContainDateEmbody(DateEmbody.Day))
                {
                    g.DrawString(this.dateBody.day_str, this.Font, ((this.dateBody.selectElementItem == DateContentSelectedTypes.Day && this.Focused) ? text_highlight_sb : text_nohighlight_sb), this.dateBody.day_rect, text_ft);
                    if (this.Content.SymbolPattern == DateInputSymbolPattern.Unit)
                    {
                        TextRenderer.DrawText(g, this.dateBody.day_unit_str, this.Font, this.dateBody.day_unit_rect, this.Enabled ? this.StyleAppearance.Normal.SymbolColor : this.StyleAppearance.Disabled.TextColor, TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter | TextFormatFlags.PreserveGraphicsClipping);
                    }
                    else
                    {
                        g.DrawString(this.dateBody.monthday_str, this.Font, symbol_sb, this.dateBody.monthday_rect, StringFormat.GenericTypographic);
                    }
                }
                if (this.IsContainDateEmbody(DateEmbody.Hour))
                {
                    g.DrawString(this.dateBody.hour_str, this.Font, ((this.dateBody.selectElementItem == DateContentSelectedTypes.Hour && this.Focused) ? text_highlight_sb : text_nohighlight_sb), this.dateBody.hour_rect, text_ft);
                    if (this.Content.SymbolPattern == DateInputSymbolPattern.Unit)
                    {
                        TextRenderer.DrawText(g, this.dateBody.hour_unit_str, this.Font, this.dateBody.hour_unit_rect, this.Enabled ? this.StyleAppearance.Normal.SymbolColor : this.StyleAppearance.Disabled.TextColor, TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter | TextFormatFlags.PreserveGraphicsClipping);
                    }
                    else
                    {
                        g.DrawString(this.dateBody.dayhour_str, this.Font, symbol_sb, this.dateBody.dayhour_rect, StringFormat.GenericTypographic);
                    }
                }
                if (this.IsContainDateEmbody(DateEmbody.Minute))
                {
                    g.DrawString(this.dateBody.minute_str, this.Font, ((this.dateBody.selectElementItem == DateContentSelectedTypes.Minute && this.Focused) ? text_highlight_sb : text_nohighlight_sb), this.dateBody.minute_rect, text_ft);
                    if (this.Content.SymbolPattern == DateInputSymbolPattern.Unit)
                    {
                        TextRenderer.DrawText(g, this.dateBody.minute_unit_str, this.Font, this.dateBody.minute_unit_rect, this.Enabled ? this.StyleAppearance.Normal.SymbolColor : this.StyleAppearance.Disabled.TextColor, TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter | TextFormatFlags.PreserveGraphicsClipping);
                    }
                    else
                    {
                        g.DrawString(this.dateBody.hourminute_str, this.Font, symbol_sb, this.dateBody.hourminute_rect, StringFormat.GenericTypographic);
                    }
                }
                if (this.IsContainDateEmbody(DateEmbody.Second))
                {
                    g.DrawString(this.dateBody.second_str, this.Font, ((this.dateBody.selectElementItem == DateContentSelectedTypes.Second && this.Focused) ? text_highlight_sb : text_nohighlight_sb), this.dateBody.second_rect, text_ft);
                    if (this.Content.SymbolPattern == DateInputSymbolPattern.Unit)
                    {
                        TextRenderer.DrawText(g, this.dateBody.second_unit_str, this.Font, this.dateBody.second_unit_rect, this.Enabled ? this.StyleAppearance.Normal.SymbolColor : this.StyleAppearance.Disabled.TextColor, TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter | TextFormatFlags.PreserveGraphicsClipping);
                    }
                    else
                    {
                        g.DrawString(this.dateBody.minutesecond_str, this.Font, symbol_sb, this.dateBody.minutesecond_rect, StringFormat.GenericTypographic);
                    }
                }
                if (this.IsContainDateEmbody(DateEmbody.Week))
                {
                    g.DrawString(this.dateBody.secondweek_str, this.Font, symbol_sb, this.dateBody.secondweek_rect, StringFormat.GenericTypographic);
                    TextRenderer.DrawText(g, this.dateBody.week_str, this.Font, this.dateBody.week_rect, this.Enabled ? this.StyleAppearance.Normal.WeekColor : this.StyleAppearance.Disabled.TextColor, TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter | TextFormatFlags.PreserveGraphicsClipping);
                }

                text_nohighlight_sb.Dispose();
                text_highlight_sb.Dispose();
                symbol_sb.Dispose();
                text_ft.Dispose();

                g.Clip = source_c_region;
                value_region.Dispose();
            }
            else
            {
                if (!String.IsNullOrWhiteSpace(this.Content.NullTipText))
                {
                    Region value_region = new Region(this.dateBody.value_rect);
                    g.Clip = value_region;

                    TextRenderer.DrawText(g, this.Content.NullTipText, this.Font, new Rectangle((int)this.dateBody.value_rect.X, (int)this.dateBody.value_rect.Y, (int)this.dateBody.value_rect.Width, (int)this.dateBody.value_rect.Height), this.Enabled ? this.StyleAppearance.NullTipTextColor : this.StyleAppearance.Disabled.TextColor, TextFormatFlags.VerticalCenter | TextFormatFlags.PreserveGraphicsClipping | (this.Content.TextAlignment == DateInputTextAlignment.Left ? TextFormatFlags.Left : TextFormatFlags.Right));

                    g.Clip = source_c_region;
                    value_region.Dispose();
                }
            }

            // 清除按钮
            if (this.ClearButton.Visible)
            {
                float radius = this.dateBody.clear_btn_rect.Width / 2 * 2 / 3;
                PointF center = new PointF(this.dateBody.clear_btn_rect.X + this.dateBody.clear_btn_rect.Width / 2, this.dateBody.clear_btn_rect.Y + this.dateBody.clear_btn_rect.Height / 2);
                PointF[] lineArr = new PointF[] { ControlHelper.CalculatePointForAngle(center, radius, 225), ControlHelper.CalculatePointForAngle(center, radius, 45), ControlHelper.CalculatePointForAngle(center, radius, 135), ControlHelper.CalculatePointForAngle(center, radius, 315) };

                SmoothingMode source_sm = g.SmoothingMode;
                CompositingQuality source_cq = g.CompositingQuality;
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.CompositingQuality = CompositingQuality.HighQuality;

                Pen clear_btn_fore_pen = new Pen((this.Enabled == true && this.ReadOnly == false) ? this.StyleAppearance.ClearButton.ForeColor : this.StyleAppearance.Disabled.TextColor, this.ScaleDpi >= 1.5 ? 3 : 2) { StartCap = LineCap.Round, EndCap = LineCap.Round };
                g.DrawLine(clear_btn_fore_pen, lineArr[0], lineArr[1]);
                g.DrawLine(clear_btn_fore_pen, lineArr[2], lineArr[3]);
                clear_btn_fore_pen.Dispose();

                g.SmoothingMode = source_sm;
                g.CompositingQuality = source_cq;

                if (this.Enabled && !this.ReadOnly && this.OperateMode == DateInputOperateModes.Editor && this.dateBody.selectElementItem == DateContentSelectedTypes.ClearButton)
                {
                    Pen activated_border_pen = new Pen(border_color) { DashStyle = DashStyle.Dash };
                    g.DrawRectangle(activated_border_pen, this.dateBody.clear_btn_rect.X, this.dateBody.clear_btn_rect.Y, this.dateBody.clear_btn_rect.Width, this.dateBody.clear_btn_rect.Height);
                    activated_border_pen.Dispose();
                }
            }

            g.Clip = source_c_region;
            content_region.Dispose();

            // 边框
            Pen border_pen = new Pen(border_color);
            g.DrawRectangle(border_pen, this.ClientRectangle.X, this.ClientRectangle.Y, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1);
            border_pen.Dispose();

            //控件激活状态虚线框
            if (this.Focused && this.ShowFocusCues)
            {
                Pen activated_border_pen = new Pen(this.StyleAppearance.ActivateColor) { DashStyle = DashStyle.Dot };
                Rectangle rect = Rectangle.Empty;
                if (this.OperateMode == DateInputOperateModes.DropDown)
                {
                    rect = new Rectangle(this.ClientRectangle.X + 3, this.ClientRectangle.Y + 3, this.ClientRectangle.Width - 7, this.ClientRectangle.Height - 7);
                }
                else if (this.OperateMode == DateInputOperateModes.Editor && this.dateBody.selectElementItem == DateContentSelectedTypes.Image)
                {
                    rect = new Rectangle(this.dateBody.image_rect.X - 1, this.dateBody.image_rect.Y - 1, this.dateBody.image_rect.Width + 1, this.dateBody.image_rect.Height + 1);

                }

                g.DrawRectangle(activated_border_pen, rect);
                activated_border_pen.Dispose();
            }

        }

        protected override void Select(bool directed, bool forward)
        {
            if (this.ReadOnly)
            {
                this.Parent.SelectNextControl(this, true, false, true, true);
                return;
            }

            base.Select(directed, forward);

            this.mouseDownAreaType = MouseDownAreaTypes.None;
            this.dateBody.selectElementItem = this.OperateMode == DateInputOperateModes.Editor ? DateContentSelectedTypes.Image : DateContentSelectedTypes.None;
            this.Invalidate();
        }

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);

            this.Invalidate();
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);

            if (this.datePickerDisplayStatus == true)
            {
                this.tsdd.Close();
            }
            this.VaildUnSelectedValue(this.dateBody.selectElementItem);

            this.Invalidate();
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            base.OnEnabledChanged(e);

            if (!this.Enabled)
            {
                if (this.datePickerDisplayStatus == true)
                {
                    this.tsdd.Close();
                }
                this.VaildUnSelectedValue(this.dateBody.selectElementItem);

                this.Invalidate();
            }
        }

        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);

            if (!this.Visible)
            {
                if (this.datePickerDisplayStatus == true)
                {
                    this.tsdd.Close();
                }
                this.VaildUnSelectedValue(this.dateBody.selectElementItem);

                this.Invalidate();
            }
        }

        protected override void OnParentChanged(EventArgs e)
        {
            base.OnParentChanged(e);

            if (this.Parent == null)
            {
                if (this.datePickerDisplayStatus == true)
                {
                    this.tsdd.Close();
                }
                this.VaildUnSelectedValue(this.dateBody.selectElementItem);

                this.Invalidate();
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (!this.ReadOnly)
            {
                if (!this.Focused)
                {
                    this.Focus();
                }

                if (e.Button == MouseButtons.Left)
                {
                    if (this.OperateMode == DateInputOperateModes.Editor)
                    {
                        if (this.dateBody.content_rect.Contains(e.Location))
                        {
                            if (this.dateBody.image_rect.Contains(e.Location))
                            {
                                this.mouseDownAreaType = MouseDownAreaTypes.Image;
                                this.dateBody.selectElementItem = DateContentSelectedTypes.Image;
                                this.Invalidate();
                            }
                            else if (this.ClearButton.Visible && this.dateBody.clear_btn_rect.Contains(e.Location))
                            {
                                this.mouseDownAreaType = MouseDownAreaTypes.ClearButton;
                            }
                            else if (this.DatePicker.DateValue.HasValue && this.dateBody.value_rect.Contains(e.Location))
                            {
                                this.mouseDownAreaType = MouseDownAreaTypes.DateText;

                                DateContentSelectedTypes tmp = DateContentSelectedTypes.None;
                                if (this.IsContainDateEmbody(DateEmbody.Year) &&
                                     (
                                      this.dateBody.year_rect.Contains(e.Location) ||
                                      (this.Content.SymbolPattern == DateInputSymbolPattern.Unit && this.dateBody.year_unit_rect.Contains(e.Location)) ||
                                      (this.Content.SymbolPattern != DateInputSymbolPattern.Unit && this.IsContainDateEmbody(DateEmbody.Month) && this.dateBody.yearmonth_rect.Contains(e.Location))
                                      )
                                    )
                                {
                                    tmp = DateContentSelectedTypes.Year;
                                }
                                else if (this.IsContainDateEmbody(DateEmbody.Month) &&
                                           (
                                            this.dateBody.month_rect.Contains(e.Location) ||
                                            (this.Content.SymbolPattern == DateInputSymbolPattern.Unit && this.dateBody.month_unit_rect.Contains(e.Location)) ||
                                            (this.Content.SymbolPattern != DateInputSymbolPattern.Unit && this.IsContainDateEmbody(DateEmbody.Day) && this.dateBody.monthday_rect.Contains(e.Location))
                                            )
                                        )
                                {
                                    tmp = DateContentSelectedTypes.Month;
                                }
                                else if (this.IsContainDateEmbody(DateEmbody.Day) &&
                                           (
                                            this.dateBody.day_rect.Contains(e.Location) ||
                                            (this.Content.SymbolPattern == DateInputSymbolPattern.Unit && this.dateBody.day_rect.Contains(e.Location))
                                            )
                                         )
                                {
                                    tmp = DateContentSelectedTypes.Day;
                                }
                                else if (this.IsContainDateEmbody(DateEmbody.Hour) &&
                                           (
                                             this.dateBody.hour_rect.Contains(e.Location) ||
                                            (this.Content.SymbolPattern == DateInputSymbolPattern.Unit && this.dateBody.hour_unit_rect.Contains(e.Location)) ||
                                            (this.Content.SymbolPattern != DateInputSymbolPattern.Unit && this.IsContainDateEmbody(DateEmbody.Minute) && this.dateBody.hourminute_rect.Contains(e.Location))
                                            )
                                         )
                                {
                                    tmp = DateContentSelectedTypes.Hour;
                                }
                                else if (this.IsContainDateEmbody(DateEmbody.Minute) &&
                                            (
                                             this.dateBody.minute_rect.Contains(e.Location) ||
                                            (this.Content.SymbolPattern == DateInputSymbolPattern.Unit && this.dateBody.minute_unit_rect.Contains(e.Location)) ||
                                            (this.Content.SymbolPattern != DateInputSymbolPattern.Unit && this.IsContainDateEmbody(DateEmbody.Second) && this.dateBody.minutesecond_rect.Contains(e.Location))
                                            )
                                         )
                                {
                                    tmp = DateContentSelectedTypes.Minute;
                                }
                                else if (this.IsContainDateEmbody(DateEmbody.Second) &&
                                            (
                                            this.dateBody.second_rect.Contains(e.Location) ||
                                            (this.Content.SymbolPattern == DateInputSymbolPattern.Unit && this.dateBody.second_unit_rect.Contains(e.Location))
                                            )
                                        )
                                {
                                    tmp = DateContentSelectedTypes.Second;
                                }

                                if (this.dateBody.selectElementItem != tmp)
                                {
                                    if (!(this.dateBody.selectElementItem == DateContentSelectedTypes.None || this.dateBody.selectElementItem == DateContentSelectedTypes.Image))
                                    {
                                        this.VaildUnSelectedValue(this.dateBody.selectElementItem);
                                    }
                                    this.dateBody.selectElementItem = tmp;
                                    this.Invalidate();
                                }
                            }
                            else
                            {
                                this.mouseDownAreaType = MouseDownAreaTypes.Main;
                            }
                        }
                        else
                        {
                            this.mouseDownAreaType = MouseDownAreaTypes.Main;
                        }

                    }
                    else
                    {
                        if (this.dateBody.content_rect.Contains(e.Location) && this.dateBody.clear_btn_rect.Contains(e.Location))
                        {
                            this.mouseDownAreaType = MouseDownAreaTypes.ClearButton;
                        }
                        else
                        {
                            this.mouseDownAreaType = MouseDownAreaTypes.Main;
                        }
                    }
                }
            }

            base.OnMouseDown(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);

            if (!this.ReadOnly)
            {
                if (e.Button == MouseButtons.Left)
                {
                    if (this.OperateMode == DateInputOperateModes.Editor)
                    {
                        if (this.ClearButton.Visible && this.mouseDownAreaType == MouseDownAreaTypes.ClearButton && this.dateBody.content_rect.Contains(e.Location) && this.dateBody.clear_btn_rect.Contains(e.Location))
                        {
                            this.VaildUnSelectedValue(this.dateBody.selectElementItem);
                            this.dateBody.selectElementItem = DateContentSelectedTypes.ClearButton;
                            this.DatePicker.DateValue = null;
                        }
                        else if (this.mouseDownAreaType == MouseDownAreaTypes.Image && this.dateBody.image_rect.Contains(e.Location))
                        {
                            this.ShowDatePicker();
                        }
                    }
                    else
                    {
                        if (this.ClearButton.Visible && this.mouseDownAreaType == MouseDownAreaTypes.ClearButton && this.dateBody.content_rect.Contains(e.Location) && this.dateBody.clear_btn_rect.Contains(e.Location))
                        {
                            this.VaildUnSelectedValue(this.dateBody.selectElementItem);
                            this.dateBody.selectElementItem = DateContentSelectedTypes.ClearButton;
                            this.DatePicker.DateValue = null;
                        }
                        else if (this.mouseDownAreaType == MouseDownAreaTypes.Main && this.ClientRectangle.Contains(e.Location))
                        {
                            this.ShowDatePicker();
                        }
                    }
                }
            }
            this.mouseDownAreaType = MouseDownAreaTypes.None;
        }

        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (!this.ReadOnly)
            {
                switch (keyData)
                {
                    case Keys.Left:
                        {
                            if (this.OperateMode == DateInputOperateModes.DropDown)
                            {
                                this.VaildUnSelectedValue(this.dateBody.selectElementItem);
                                this.dateBody.selectElementItem = DateContentSelectedTypes.None;
                                this.Invalidate();
                            }
                            else
                            {
                                if (!this.DatePicker.DateValue.HasValue || this.dateBody.selectElementItem == DateContentSelectedTypes.None)
                                {
                                    this.VaildUnSelectedValue(this.dateBody.selectElementItem);
                                    this.dateBody.selectElementItem = DateContentSelectedTypes.Image;
                                    this.Invalidate();
                                }
                                else
                                {
                                    int index = -1;
                                    for (int i = 0; i < this.dateBodyElements.Count; i++)
                                    {
                                        if (this.dateBodyElements[i] == this.dateBody.selectElementItem)
                                        {
                                            index = i;
                                            break;
                                        }
                                    }

                                    if (index > -1)
                                    {
                                        index -= 1;
                                        if (index < 0)
                                        {
                                            index = this.dateBodyElements.Count - 1;
                                        }

                                        this.VaildUnSelectedValue(this.dateBody.selectElementItem);
                                        this.dateBody.selectElementItem = this.dateBodyElements[index];
                                        this.Invalidate();
                                    }
                                }
                            }
                            return true;
                        }
                    case Keys.Right:
                        {
                            if (this.OperateMode == DateInputOperateModes.DropDown)
                            {
                                this.VaildUnSelectedValue(this.dateBody.selectElementItem);
                                this.dateBody.selectElementItem = DateContentSelectedTypes.None;
                                this.Invalidate();
                            }
                            else
                            {
                                if (!this.DatePicker.DateValue.HasValue || this.dateBody.selectElementItem == DateContentSelectedTypes.None)
                                {
                                    this.VaildUnSelectedValue(this.dateBody.selectElementItem);
                                    this.dateBody.selectElementItem = DateContentSelectedTypes.Image;
                                    this.Invalidate();
                                }
                                else
                                {
                                    int index = -1;
                                    for (int i = 0; i < this.dateBodyElements.Count; i++)
                                    {
                                        if (this.dateBodyElements[i] == this.dateBody.selectElementItem)
                                        {
                                            index = i;
                                            break;
                                        }
                                    }

                                    if (index > -1)
                                    {
                                        index += 1;
                                        if (index >= this.dateBodyElements.Count)
                                        {
                                            index = 0;
                                        }

                                        this.VaildUnSelectedValue(this.dateBody.selectElementItem);
                                        this.dateBody.selectElementItem = this.dateBodyElements[index];
                                        this.Invalidate();
                                    }
                                }
                            }
                            return true;
                        }
                    case Keys.Up:
                        {
                            if (this.dateBody.selectElementItem == DateContentSelectedTypes.Year)
                            {
                                //年验证
                                int year = int.Parse(this.dateBody.year_str) + 1;
                                year = Math.Min(year, 9999);
                                year = Math.Min(year, this.DatePicker.MaxValue.Year);
                                year = Math.Max(year, 1);
                                year = Math.Max(year, this.DatePicker.MinValue.Year);
                                //月验证
                                int month = int.Parse(this.dateBody.month_str);
                                int ym_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0'));
                                int ym_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMM"));
                                int ym_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMM"));
                                if (ym_now_int > ym_max_int)
                                {
                                    month = (year == this.DatePicker.MaxValue.Year) ? this.DatePicker.MaxValue.Month : 12;
                                }
                                if (ym_now_int < ym_min_int)
                                {
                                    month = (year == this.DatePicker.MinValue.Year) ? this.DatePicker.MinValue.Month : 1;
                                }
                                //日验证
                                int days = DateTime.DaysInMonth(year, month);
                                int day = int.Parse(this.dateBody.day_str);
                                day = Math.Min(day, days);
                                ym_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0'));
                                int ymd_day_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0') + day.ToString().PadLeft(2, '0'));
                                int ymd_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMMdd"));
                                int ymd_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMMdd"));
                                if (ymd_day_int > ymd_max_int)
                                {
                                    day = (ym_now_int == ym_max_int) ? this.DatePicker.MaxValue.Day : days;
                                }
                                if (ymd_day_int < ymd_min_int)
                                {
                                    day = (ym_now_int == ym_min_int) ? this.DatePicker.MinValue.Day : 1;
                                }

                                this.dateBody.year_str = year.ToString().PadLeft(4, '0');
                                this.dateBody.month_str = month.ToString().PadLeft(2, '0');
                                this.dateBody.day_str = day.ToString().PadLeft(2, '0');
                                this.dateBody.week_str = this.GetWeekNameForDateTime(new DateTime(year, month, day));
                                this.SetTextToDatePickerValue();
                            }
                            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Month)
                            {
                                //月验证
                                int year = int.Parse(this.dateBody.year_str);
                                int month = int.Parse(this.dateBody.month_str) + 1;
                                if (month > 12)
                                {
                                    month = 1;
                                }
                                int ym_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0'));
                                int ym_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMM"));
                                int ym_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMM"));
                                if (ym_now_int > ym_max_int)
                                {
                                    month = this.DatePicker.MaxValue.Month;
                                }
                                if (ym_now_int < ym_min_int)
                                {
                                    month = this.DatePicker.MinValue.Month;
                                }
                                //日验证
                                int days = DateTime.DaysInMonth(year, month);
                                int day = int.Parse(this.dateBody.day_str);
                                day = Math.Min(day, days);
                                ym_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0'));
                                int ymd_day_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0') + day.ToString().PadLeft(2, '0'));
                                int ymd_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMMdd"));
                                int ymd_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMMdd"));
                                if (ymd_day_int > ymd_max_int)
                                {
                                    day = (ym_now_int == ym_max_int) ? this.DatePicker.MaxValue.Day : days;
                                }
                                if (ymd_day_int < ymd_min_int)
                                {
                                    day = (ym_now_int == ym_min_int) ? this.DatePicker.MinValue.Day : 1;
                                }

                                this.dateBody.month_str = month.ToString().PadLeft(2, '0');
                                this.dateBody.day_str = day.ToString().PadLeft(2, '0');
                                this.dateBody.week_str = this.GetWeekNameForDateTime(new DateTime(year, month, day));
                                this.SetTextToDatePickerValue();
                            }
                            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Day)
                            {
                                //日验证
                                int year = int.Parse(this.dateBody.year_str);
                                int month = int.Parse(this.dateBody.month_str);
                                int days = DateTime.DaysInMonth(year, month);
                                int day = int.Parse(this.dateBody.day_str) + 1;
                                int ymd_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0') + day.ToString().PadLeft(2, '0'));
                                int ymd_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMMdd"));
                                int ymd_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMMdd"));
                                if (day > days)
                                {
                                    day = 1;
                                }
                                if (ymd_now_int > ymd_max_int)
                                {
                                    day = this.DatePicker.MaxValue.Day;
                                }
                                if (ymd_now_int < ymd_min_int)
                                {
                                    day = this.DatePicker.MinValue.Day;
                                }

                                this.dateBody.day_str = day.ToString().PadLeft(2, '0');
                                this.dateBody.week_str = this.GetWeekNameForDateTime(new DateTime(year, month, day));
                                this.SetTextToDatePickerValue();
                            }
                            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Hour)
                            {
                                int hour = int.Parse(this.dateBody.hour_str) + 1;
                                if (hour > 23)
                                {
                                    hour = 0;
                                }

                                this.dateBody.hour_str = hour.ToString().PadLeft(2, '0');
                                this.SetTextToDatePickerValue();
                            }
                            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Minute)
                            {
                                int minute = int.Parse(this.dateBody.minute_str) + 1;
                                if (minute > 59)
                                {
                                    minute = 0;
                                }

                                this.dateBody.minute_str = minute.ToString().PadLeft(2, '0');
                                this.SetTextToDatePickerValue();
                            }
                            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Second)
                            {
                                int second = int.Parse(this.dateBody.second_str) + 1;
                                if (second > 59)
                                {
                                    second = 0;
                                }

                                this.dateBody.second_str = second.ToString().PadLeft(2, '0');
                                this.SetTextToDatePickerValue();
                            }
                            return true;
                        }
                    case Keys.Down:
                        {
                            if (this.dateBody.selectElementItem == DateContentSelectedTypes.Year)
                            {
                                //年验证
                                int year = int.Parse(this.dateBody.year_str) - 1;
                                year = Math.Min(year, 9999);
                                year = Math.Min(year, this.DatePicker.MaxValue.Year);
                                year = Math.Max(year, 1);
                                year = Math.Max(year, this.DatePicker.MinValue.Year);
                                //月验证
                                int month = int.Parse(this.dateBody.month_str);
                                int ym_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0'));
                                int ym_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMM"));
                                int ym_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMM"));
                                if (ym_now_int > ym_max_int)
                                {
                                    month = (year == this.DatePicker.MaxValue.Year) ? this.DatePicker.MaxValue.Month : 12;
                                }
                                if (ym_now_int < ym_min_int)
                                {
                                    month = (year == this.DatePicker.MinValue.Year) ? this.DatePicker.MinValue.Month : 1;
                                }
                                //日验证
                                int days = DateTime.DaysInMonth(year, month);
                                int day = int.Parse(this.dateBody.day_str);
                                day = Math.Min(day, days);
                                ym_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0'));
                                int ymd_day_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0') + day.ToString().PadLeft(2, '0'));
                                int ymd_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMMdd"));
                                int ymd_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMMdd"));
                                if (ymd_day_int > ymd_max_int)
                                {
                                    day = (ym_now_int == ym_max_int) ? this.DatePicker.MaxValue.Day : days;
                                }
                                if (ymd_day_int < ymd_min_int)
                                {
                                    day = (ym_now_int == ym_min_int) ? this.DatePicker.MinValue.Day : 1;
                                }

                                this.dateBody.year_str = year.ToString().PadLeft(4, '0');
                                this.dateBody.month_str = month.ToString().PadLeft(2, '0');
                                this.dateBody.day_str = day.ToString().PadLeft(2, '0');
                                this.dateBody.week_str = this.GetWeekNameForDateTime(new DateTime(year, month, day));
                                this.SetTextToDatePickerValue();
                            }
                            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Month)
                            {
                                //月验证
                                int year = int.Parse(this.dateBody.year_str);
                                int month = int.Parse(this.dateBody.month_str) - 1;
                                if (month < 1)
                                {
                                    month = 12;
                                }
                                int ym_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0'));
                                int ym_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMM"));
                                int ym_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMM"));
                                if (ym_now_int > ym_max_int)
                                {
                                    month = this.DatePicker.MaxValue.Month;
                                }
                                if (ym_now_int < ym_min_int)
                                {
                                    month = this.DatePicker.MinValue.Month;
                                }
                                //日验证
                                int days = DateTime.DaysInMonth(year, month);
                                int day = int.Parse(this.dateBody.day_str);
                                day = Math.Min(day, days);
                                ym_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0'));
                                int ymd_day_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0') + day.ToString().PadLeft(2, '0'));
                                int ymd_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMMdd"));
                                int ymd_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMMdd"));
                                if (ymd_day_int > ymd_max_int)
                                {
                                    day = (ym_now_int == ym_max_int) ? this.DatePicker.MaxValue.Day : days;
                                }
                                if (ymd_day_int < ymd_min_int)
                                {
                                    day = (ym_now_int == ym_min_int) ? this.DatePicker.MinValue.Day : 1;
                                }

                                this.dateBody.month_str = month.ToString().PadLeft(2, '0');
                                this.dateBody.day_str = day.ToString().PadLeft(2, '0');
                                this.dateBody.week_str = this.GetWeekNameForDateTime(new DateTime(year, month, day));
                                this.SetTextToDatePickerValue();
                            }
                            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Day)
                            {
                                //日验证
                                int year = int.Parse(this.dateBody.year_str);
                                int month = int.Parse(this.dateBody.month_str);
                                int days = DateTime.DaysInMonth(year, month);
                                int day = int.Parse(this.dateBody.day_str) - 1;
                                int ymd_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0') + day.ToString().PadLeft(2, '0'));
                                int ymd_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMMdd"));
                                int ymd_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMMdd"));
                                if (day < 1)
                                {
                                    day = days;
                                }
                                if (ymd_now_int > ymd_max_int)
                                {
                                    day = this.DatePicker.MaxValue.Day;
                                }
                                if (ymd_now_int < ymd_min_int)
                                {
                                    day = this.DatePicker.MinValue.Day;
                                }

                                this.dateBody.day_str = day.ToString().PadLeft(2, '0');
                                this.dateBody.week_str = this.GetWeekNameForDateTime(new DateTime(year, month, day));
                                this.SetTextToDatePickerValue();
                            }
                            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Hour)
                            {
                                int hour = int.Parse(this.dateBody.hour_str) - 1;
                                if (hour < 0)
                                {
                                    hour = 23;
                                }

                                this.dateBody.hour_str = hour.ToString().PadLeft(2, '0');
                                this.SetTextToDatePickerValue();
                            }
                            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Minute)
                            {
                                int minute = int.Parse(this.dateBody.minute_str) - 1;
                                if (minute < 0)
                                {
                                    minute = 59;
                                }

                                this.dateBody.minute_str = minute.ToString().PadLeft(2, '0');
                                this.SetTextToDatePickerValue();
                            }
                            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Second)
                            {
                                int second = int.Parse(this.dateBody.second_str) - 1;
                                if (second < 0)
                                {
                                    second = 59;
                                }

                                this.dateBody.second_str = second.ToString().PadLeft(2, '0');
                                this.SetTextToDatePickerValue();
                            }
                            return true;
                        }
                    case Keys.D0:
                    case Keys.NumPad0:
                        {
                            this.UpdateDateBodyValueByKeyboard(0);
                            return true;
                        }
                    case Keys.D1:
                    case Keys.NumPad1:
                        {
                            this.UpdateDateBodyValueByKeyboard(1);
                            return true;
                        }
                    case Keys.D2:
                    case Keys.NumPad2:
                        {
                            this.UpdateDateBodyValueByKeyboard(2);
                            return true;
                        }
                    case Keys.D3:
                    case Keys.NumPad3:
                        {
                            this.UpdateDateBodyValueByKeyboard(3);
                            return true;
                        }
                    case Keys.D4:
                    case Keys.NumPad4:
                        {
                            this.UpdateDateBodyValueByKeyboard(4);
                            return true;
                        }
                    case Keys.D5:
                    case Keys.NumPad5:
                        {
                            this.UpdateDateBodyValueByKeyboard(5);
                            return true;
                        }
                    case Keys.D6:
                    case Keys.NumPad6:
                        {
                            this.UpdateDateBodyValueByKeyboard(6);
                            return true;
                        }
                    case Keys.D7:
                    case Keys.NumPad7:
                        {
                            this.UpdateDateBodyValueByKeyboard(7);
                            return true;
                        }
                    case Keys.D8:
                    case Keys.NumPad8:
                        {
                            this.UpdateDateBodyValueByKeyboard(8);
                            return true;
                        }
                    case Keys.D9:
                    case Keys.NumPad9:
                        {
                            this.UpdateDateBodyValueByKeyboard(9);
                            return true;
                        }
                    case Keys.Enter:
                        {
                            if (this.OperateMode == DateInputOperateModes.DropDown)
                            {

                                if (this.dateBody.selectElementItem == DateContentSelectedTypes.ClearButton)
                                {
                                    this.VaildUnSelectedValue(this.dateBody.selectElementItem);
                                    this.DatePicker.DateValue = null;
                                }
                                else
                                {
                                    this.ShowDatePicker();
                                }
                            }
                            else
                            {
                                if (this.dateBody.selectElementItem == DateContentSelectedTypes.ClearButton)
                                {
                                    this.VaildUnSelectedValue(this.dateBody.selectElementItem);
                                    this.DatePicker.DateValue = null;
                                }
                                else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Image)
                                {
                                    this.ShowDatePicker();
                                }
                            }
                            return true;
                        }
                }
            }

            return base.ProcessDialogKey(keyData);
        }

        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
        {
            base.SetBoundsCore(x, y, width, this.GetControlAutoHeight(), specified);

            this.InitializeElement();
            this.Invalidate();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this.Icon.Image != null)
                {
                    this.Icon.Image = null;
                }
                if (this.disable_image_tmp != null)
                {
                    this.disable_image_tmp.Dispose();
                    this.disable_image_tmp = null;
                }
                if (this.DatePicker != null)
                {
                    this.DatePicker.Dispose();
                    this.DatePicker = null;
                }
                if (this.tsch != null)
                {
                    this.tsch.Dispose();
                    this.tsch = null;
                }
                if (this.tsdd != null)
                {
                    this.tsdd.Dispose();
                    this.tsdd = null;
                }
            }
            base.Dispose(disposing);
        }

        #endregion

        #region 公开方法

        /// <summary>
        /// 初始化控件内部元素布局
        /// </summary>
        public void InitializeElement()
        {
            int scale_contentPadding = (int)Math.Ceiling(this.Content.Padding * this.ScaleDpi);
            int scale_image_value_padding = (int)Math.Ceiling(this.image_value_space * this.ScaleDpi);
            int scale_image_width = this.dateBody.year_size.Height;
            int scale_image_height = this.dateBody.year_size.Height;
            int scale_clear_btn_width = this.ClearButton.Visible ? scale_image_width : 0;
            int scale_clear_btn_height = this.ClearButton.Visible ? scale_image_height : 0;

            this.dateBody.content_rect = new Rectangle(this.ClientRectangle.X + this.borderThickness + scale_contentPadding, this.ClientRectangle.Y + this.borderThickness + scale_contentPadding, this.ClientRectangle.Width - this.borderThickness * 2 - scale_contentPadding * 2, this.ClientRectangle.Height - this.borderThickness * 2 - scale_contentPadding * 2);

            if (this.Icon.Alignment == DateInputImageAlignment.Right)
            {
                this.dateBody.image_rect = new Rectangle(this.ClientRectangle.Right - this.borderThickness - scale_contentPadding - scale_image_width, this.ClientRectangle.Y + (this.ClientRectangle.Height - scale_image_height) / 2, scale_image_width, scale_image_height);
                if (this.ClearButton.Visible == false)
                {
                    this.dateBody.value_rect = new Rectangle(this.ClientRectangle.X + this.borderThickness + scale_contentPadding, this.ClientRectangle.Y + this.borderThickness + scale_contentPadding, this.ClientRectangle.Width - this.borderThickness * 2 - scale_contentPadding * 2 - scale_image_width - scale_image_value_padding, this.ClientRectangle.Height - this.borderThickness * 2 - scale_contentPadding * 2);
                }
                else
                {
                    if (this.ClearButton.Alignment == DateInputClearAlignment.Near)
                    {
                        this.dateBody.clear_btn_rect = new Rectangle(this.ClientRectangle.Right - this.borderThickness - scale_contentPadding - scale_image_width - scale_image_value_padding - scale_clear_btn_width, this.ClientRectangle.Y + (this.ClientRectangle.Height - scale_clear_btn_height) / 2, scale_clear_btn_height, scale_clear_btn_width);
                        this.dateBody.value_rect = new Rectangle(this.ClientRectangle.X + this.borderThickness + scale_contentPadding, this.ClientRectangle.Y + this.borderThickness + scale_contentPadding, this.ClientRectangle.Width - this.borderThickness * 2 - scale_contentPadding * 2 - scale_image_width - scale_image_value_padding - scale_clear_btn_width - scale_image_value_padding, this.ClientRectangle.Height - this.borderThickness * 2 - scale_contentPadding * 2);
                    }
                    else
                    {
                        this.dateBody.clear_btn_rect = new Rectangle(this.ClientRectangle.X + this.borderThickness + scale_contentPadding, this.ClientRectangle.Y + (this.ClientRectangle.Height - scale_clear_btn_height) / 2, scale_clear_btn_width, scale_clear_btn_height);
                        this.dateBody.value_rect = new Rectangle(this.ClientRectangle.X + this.borderThickness + scale_contentPadding + scale_clear_btn_width + scale_image_value_padding, this.ClientRectangle.Y + this.borderThickness + scale_contentPadding, this.ClientRectangle.Width - this.borderThickness * 2 - scale_contentPadding * 2 - scale_image_width - scale_image_value_padding - scale_clear_btn_width - scale_image_value_padding, this.ClientRectangle.Height - this.borderThickness * 2 - scale_contentPadding * 2);
                    }
                }
            }
            else
            {
                this.dateBody.image_rect = new Rectangle(this.ClientRectangle.X + this.borderThickness + scale_contentPadding, this.ClientRectangle.Y + (this.ClientRectangle.Height - scale_image_height) / 2, scale_image_width, scale_image_height);
                if (this.ClearButton.Visible == false)
                {
                    this.dateBody.value_rect = new Rectangle(this.ClientRectangle.X + this.borderThickness + scale_contentPadding + scale_image_width + scale_image_value_padding, this.ClientRectangle.Y + this.borderThickness + scale_contentPadding, this.ClientRectangle.Width - this.borderThickness * 2 - scale_contentPadding * 2 - scale_image_width - scale_image_value_padding, this.ClientRectangle.Height - this.borderThickness * 2 - scale_contentPadding * 2);
                }
                else
                {
                    if (this.ClearButton.Alignment == DateInputClearAlignment.Near)
                    {
                        this.dateBody.clear_btn_rect = new Rectangle(this.ClientRectangle.X + this.borderThickness + scale_contentPadding + scale_image_width + scale_image_value_padding, this.ClientRectangle.Y + (this.ClientRectangle.Height - scale_clear_btn_height) / 2, scale_clear_btn_width, scale_clear_btn_height);
                        this.dateBody.value_rect = new Rectangle(this.ClientRectangle.X + this.borderThickness + scale_contentPadding + scale_image_width + scale_image_value_padding + scale_clear_btn_width + scale_image_value_padding, this.ClientRectangle.Y + this.borderThickness + scale_contentPadding, this.ClientRectangle.Width - this.borderThickness * 2 - scale_contentPadding * 2 - scale_image_width - scale_image_value_padding - scale_clear_btn_width - scale_image_value_padding, this.ClientRectangle.Height - this.borderThickness * 2 - scale_contentPadding * 2);
                    }
                    else
                    {
                        this.dateBody.clear_btn_rect = new Rectangle(this.ClientRectangle.Right - this.borderThickness - scale_clear_btn_width - scale_contentPadding, this.ClientRectangle.Y + (this.ClientRectangle.Height - scale_clear_btn_height) / 2, scale_clear_btn_height, scale_clear_btn_width);
                        this.dateBody.value_rect = new Rectangle(this.ClientRectangle.X + this.borderThickness + scale_contentPadding + scale_image_width + scale_image_value_padding, this.ClientRectangle.Y + this.borderThickness + scale_contentPadding, this.ClientRectangle.Width - this.borderThickness * 2 - scale_contentPadding * 2 - scale_image_width - scale_image_value_padding - scale_clear_btn_width - scale_image_value_padding, this.ClientRectangle.Height - this.borderThickness * 2 - scale_contentPadding * 2);
                    }
                }
            }

            if (this.Content.TextAlignment == DateInputTextAlignment.Left)
            {
                int x = this.dateBody.value_rect.Left;
                this.dateBody.year_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.year_size.Height) / 2, this.dateBody.year_size.Width, this.dateBody.year_size.Height);
                x = this.dateBody.year_rect.Right;
                this.dateBody.year_unit_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.year_unit_size.Height) / 2, this.dateBody.year_unit_size.Width, this.dateBody.year_unit_size.Height);
                x = this.dateBody.year_unit_rect.Right;
                this.dateBody.yearmonth_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.yearmonth_size.Height) / 2, this.dateBody.yearmonth_size.Width, this.dateBody.yearmonth_size.Height);
                x = this.dateBody.yearmonth_rect.Right;
                this.dateBody.month_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.month_size.Height) / 2, this.dateBody.month_size.Width, this.dateBody.month_size.Height);
                x = this.dateBody.month_rect.Right;
                this.dateBody.month_unit_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.month_unit_size.Height) / 2, this.dateBody.month_unit_size.Width, this.dateBody.month_unit_size.Height);
                x = this.dateBody.month_unit_rect.Right;
                this.dateBody.monthday_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.monthday_size.Height) / 2, this.dateBody.monthday_size.Width, this.dateBody.monthday_size.Height);
                x = this.dateBody.monthday_rect.Right;
                this.dateBody.day_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.day_size.Height) / 2, this.dateBody.day_size.Width, this.dateBody.day_size.Height);
                x = this.dateBody.day_rect.Right;
                this.dateBody.day_unit_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.day_unit_size.Height) / 2, this.dateBody.day_unit_size.Width, this.dateBody.day_unit_size.Height);
                x = this.dateBody.day_unit_rect.Right;
                this.dateBody.dayhour_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.dayhour_size.Height) / 2, this.dateBody.dayhour_size.Width, this.dateBody.dayhour_size.Height);
                x = this.dateBody.dayhour_rect.Right;
                this.dateBody.hour_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.hour_size.Height) / 2, this.dateBody.hour_size.Width, this.dateBody.hour_size.Height);
                x = this.dateBody.hour_rect.Right;
                this.dateBody.hour_unit_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.hour_unit_size.Height) / 2, this.dateBody.hour_unit_size.Width, this.dateBody.hour_unit_size.Height);
                x = this.dateBody.hour_unit_rect.Right;
                this.dateBody.hourminute_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.hourminute_size.Height) / 2, this.dateBody.hourminute_size.Width, this.dateBody.hourminute_size.Height);
                x = this.dateBody.hourminute_rect.Right;
                this.dateBody.minute_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.minute_size.Height) / 2, this.dateBody.minute_size.Width, this.dateBody.minute_size.Height);
                x = this.dateBody.minute_rect.Right;
                this.dateBody.minute_unit_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.minute_unit_size.Height) / 2, this.dateBody.minute_unit_size.Width, this.dateBody.minute_unit_size.Height);
                x = this.dateBody.minute_unit_rect.Right;
                this.dateBody.minutesecond_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.minutesecond_size.Height) / 2, this.dateBody.minutesecond_size.Width, this.dateBody.minutesecond_size.Height);
                x = this.dateBody.minutesecond_rect.Right;
                this.dateBody.second_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.second_size.Height) / 2, this.dateBody.second_size.Width, this.dateBody.second_size.Height);
                x = this.dateBody.second_rect.Right;
                this.dateBody.second_unit_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.second_unit_size.Height) / 2, this.dateBody.second_unit_size.Width, this.dateBody.second_unit_size.Height);
                x = this.dateBody.second_unit_rect.Right;
                this.dateBody.secondweek_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.secondweek_size.Height) / 2, this.dateBody.secondweek_size.Width, this.dateBody.secondweek_size.Height);
                x = this.dateBody.secondweek_rect.Right;
                this.dateBody.week_rect = new Rectangle(x, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.week_size.Height) / 2, this.dateBody.week_size.Width, this.dateBody.week_size.Height);
                x = this.dateBody.week_rect.Right;
            }
            else
            {
                int r = this.dateBody.value_rect.Right;
                this.dateBody.week_rect = new Rectangle(r - this.dateBody.week_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.week_size.Height) / 2, this.dateBody.week_size.Width, this.dateBody.week_size.Height);
                r = this.dateBody.week_rect.X;
                this.dateBody.secondweek_rect = new Rectangle(r - this.dateBody.secondweek_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.secondweek_size.Height) / 2, this.dateBody.secondweek_size.Width, this.dateBody.secondweek_size.Height);
                r = this.dateBody.secondweek_rect.X;
                this.dateBody.second_unit_rect = new Rectangle(r - this.dateBody.second_unit_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.second_unit_size.Height) / 2, this.dateBody.second_unit_size.Width, this.dateBody.second_unit_size.Height);
                r = this.dateBody.second_unit_rect.X;
                this.dateBody.second_rect = new Rectangle(r - this.dateBody.second_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.second_size.Height) / 2, this.dateBody.second_size.Width, this.dateBody.second_size.Height);
                r = this.dateBody.second_rect.X;
                this.dateBody.minutesecond_rect = new Rectangle(r - this.dateBody.minutesecond_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.minutesecond_size.Height) / 2, this.dateBody.minutesecond_size.Width, this.dateBody.minutesecond_size.Height);
                r = this.dateBody.minutesecond_rect.X;
                this.dateBody.minute_unit_rect = new Rectangle(r - this.dateBody.minute_unit_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.minute_unit_size.Height) / 2, this.dateBody.minute_unit_size.Width, this.dateBody.minute_unit_size.Height);
                r = this.dateBody.minute_unit_rect.X;
                this.dateBody.minute_rect = new Rectangle(r - this.dateBody.minute_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.minute_size.Height) / 2, this.dateBody.minute_size.Width, this.dateBody.minute_size.Height);
                r = this.dateBody.minute_rect.X;
                this.dateBody.hourminute_rect = new Rectangle(r - this.dateBody.hourminute_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.hourminute_size.Height) / 2, this.dateBody.hourminute_size.Width, this.dateBody.hourminute_size.Height);
                r = this.dateBody.hourminute_rect.X;
                this.dateBody.hour_unit_rect = new Rectangle(r - this.dateBody.hour_unit_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.hour_unit_size.Height) / 2, this.dateBody.hour_unit_size.Width, this.dateBody.hour_unit_size.Height);
                r = this.dateBody.hour_unit_rect.X;
                this.dateBody.hour_rect = new Rectangle(r - this.dateBody.hour_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.hour_size.Height) / 2, this.dateBody.hour_size.Width, this.dateBody.hour_size.Height);
                r = this.dateBody.hour_rect.X;
                this.dateBody.dayhour_rect = new Rectangle(r - this.dateBody.dayhour_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.dayhour_size.Height) / 2, this.dateBody.dayhour_size.Width, this.dateBody.dayhour_size.Height);
                r = this.dateBody.dayhour_rect.X;
                this.dateBody.day_unit_rect = new Rectangle(r - this.dateBody.day_unit_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.day_unit_size.Height) / 2, this.dateBody.day_unit_size.Width, this.dateBody.day_unit_size.Height);
                r = this.dateBody.day_unit_rect.X;
                this.dateBody.day_rect = new Rectangle(r - this.dateBody.day_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.day_size.Height) / 2, this.dateBody.day_size.Width, this.dateBody.day_size.Height);
                r = this.dateBody.day_rect.X;
                this.dateBody.monthday_rect = new Rectangle(r - this.dateBody.monthday_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.monthday_size.Height) / 2, this.dateBody.monthday_size.Width, this.dateBody.monthday_size.Height);
                r = this.dateBody.monthday_rect.X;
                this.dateBody.month_unit_rect = new Rectangle(r - this.dateBody.month_unit_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.month_unit_size.Height) / 2, this.dateBody.month_unit_size.Width, this.dateBody.month_unit_size.Height);
                r = this.dateBody.month_unit_rect.X;
                this.dateBody.month_rect = new Rectangle(r - this.dateBody.month_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.month_size.Height) / 2, this.dateBody.month_size.Width, this.dateBody.month_size.Height);
                r = this.dateBody.month_rect.X;
                this.dateBody.yearmonth_rect = new Rectangle(r - this.dateBody.yearmonth_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.yearmonth_size.Height) / 2, this.dateBody.yearmonth_size.Width, this.dateBody.yearmonth_size.Height);
                r = this.dateBody.yearmonth_rect.X;
                this.dateBody.year_unit_rect = new Rectangle(r - this.dateBody.year_unit_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.year_unit_size.Height) / 2, this.dateBody.year_unit_size.Width, this.dateBody.year_unit_size.Height);
                r = this.dateBody.year_unit_rect.X;
                this.dateBody.year_rect = new Rectangle(r - this.dateBody.year_size.Width, this.dateBody.value_rect.Top + (this.dateBody.value_rect.Height - this.dateBody.year_size.Height) / 2, this.dateBody.year_size.Width, this.dateBody.year_size.Height);
                r = this.dateBody.year_rect.X;
            }

        }

        #endregion 

        #region 私有方法

        /// <summary>
        /// 更新时间符号文本
        /// </summary>
        private void UpdateDateSymbol()
        {
            this.dateBody.year_unit_str = "";
            this.dateBody.yearmonth_str = "";
            this.dateBody.month_unit_str = "";
            this.dateBody.monthday_str = "";
            this.dateBody.day_unit_str = "";
            this.dateBody.dayhour_str = "";
            this.dateBody.hour_unit_str = "";
            this.dateBody.hourminute_str = "";
            this.dateBody.minute_unit_str = "";
            this.dateBody.minutesecond_str = "";
            this.dateBody.second_unit_str = "";
            this.dateBody.secondweek_str = "";
            this.dateBody.week_str = "";

            if (this.Content.SymbolPattern == DateInputSymbolPattern.CrossLine)
            {
                if (this.IsContainDateEmbody(DateEmbody.Month))
                {
                    this.dateBody.yearmonth_str = "-";
                }
                if (this.IsContainDateEmbody(DateEmbody.Day))
                {
                    this.dateBody.monthday_str = "-";
                }
                if (this.IsContainDateEmbody(DateEmbody.Hour))
                {
                    this.dateBody.dayhour_str = " ";
                }
                if (this.IsContainDateEmbody(DateEmbody.Minute))
                {
                    this.dateBody.hourminute_str = ":";
                }
                if (this.IsContainDateEmbody(DateEmbody.Second))
                {
                    this.dateBody.minutesecond_str = ":";
                }
                if (this.IsContainDateEmbody(DateEmbody.Week))
                {
                    this.dateBody.secondweek_str = " ";
                    this.dateBody.week_str = this.GetWeekNameForDateTime(this.DatePicker.DateValue);
                }
            }
            else if (this.Content.SymbolPattern == DateInputSymbolPattern.ObliqueLine)
            {
                if (this.IsContainDateEmbody(DateEmbody.Month))
                {
                    this.dateBody.yearmonth_str = "/";
                }
                if (this.IsContainDateEmbody(DateEmbody.Day))
                {
                    this.dateBody.monthday_str = "/";
                }
                if (this.IsContainDateEmbody(DateEmbody.Hour))
                {
                    this.dateBody.dayhour_str = " ";
                }
                if (this.IsContainDateEmbody(DateEmbody.Minute))
                {
                    this.dateBody.hourminute_str = ":";
                }
                if (this.IsContainDateEmbody(DateEmbody.Second))
                {
                    this.dateBody.minutesecond_str = ":";
                }
                if (this.IsContainDateEmbody(DateEmbody.Week))
                {
                    this.dateBody.secondweek_str = " ";
                    this.dateBody.week_str = this.GetWeekNameForDateTime(this.DatePicker.DateValue);
                }
            }
            else if (this.Content.SymbolPattern == DateInputSymbolPattern.Dot)
            {
                if (this.IsContainDateEmbody(DateEmbody.Month))
                {
                    this.dateBody.yearmonth_str = ".";
                }
                if (this.IsContainDateEmbody(DateEmbody.Day))
                {
                    this.dateBody.monthday_str = ".";
                }
                if (this.IsContainDateEmbody(DateEmbody.Hour))
                {
                    this.dateBody.dayhour_str = " ";
                }
                if (this.IsContainDateEmbody(DateEmbody.Minute))
                {
                    this.dateBody.hourminute_str = ":";
                }
                if (this.IsContainDateEmbody(DateEmbody.Second))
                {
                    this.dateBody.minutesecond_str = ":";
                }
                if (this.IsContainDateEmbody(DateEmbody.Week))
                {
                    this.dateBody.secondweek_str = " ";
                    this.dateBody.week_str = this.GetWeekNameForDateTime(this.DatePicker.DateValue);
                }

            }
            else if (this.Content.SymbolPattern == DateInputSymbolPattern.Unit)
            {
                if (this.IsContainDateEmbody(DateEmbody.Year))
                {
                    this.dateBody.year_unit_str = "年";
                }
                if (this.IsContainDateEmbody(DateEmbody.Month))
                {
                    this.dateBody.month_unit_str = "月";
                }
                if (this.IsContainDateEmbody(DateEmbody.Day))
                {
                    this.dateBody.day_unit_str = "日";
                }
                if (this.IsContainDateEmbody(DateEmbody.Hour))
                {
                    this.dateBody.dayhour_str = " ";
                    this.dateBody.hour_unit_str = "时";
                }
                if (this.IsContainDateEmbody(DateEmbody.Minute))
                {
                    this.dateBody.minute_unit_str = "分";
                }
                if (this.IsContainDateEmbody(DateEmbody.Second))
                {
                    this.dateBody.second_unit_str = "秒";
                }
                if (this.IsContainDateEmbody(DateEmbody.Week))
                {
                    this.dateBody.secondweek_str = " ";
                    this.dateBody.week_str = this.GetWeekNameForDateTime(this.DatePicker.DateValue);
                }
            }

            this.CalculationDateBodyElementSize();
        }

        /// <summary>
        /// 计算时间各部分元素的Size（一般由 this.Font、this.DateSymbolFormats、this.DatePicker.DateDisplayType 的更改触发）
        /// </summary>
        private void CalculationDateBodyElementSize()
        {
            IntPtr hDC = IntPtr.Zero;
            Graphics g = null;
            ControlHelper.GetWindowClientGraphics(this.Handle, out g, out hDC);


            this.dateBody.year_size = (!this.IsContainDateEmbody(DateEmbody.Year)) ? Size.Empty : Size.Ceiling(g.MeasureString(this.dateBody.year_str.Replace(" ", "").PadLeft(4, '0'), this.Font, int.MaxValue, StringFormat.GenericTypographic));
            this.dateBody.year_unit_size = Size.Ceiling(TextRenderer.MeasureText(g, this.dateBody.year_unit_str.Replace(' ', '0'), this.Font));
            this.dateBody.yearmonth_size = Size.Ceiling(g.MeasureString(this.dateBody.yearmonth_str.Replace(' ', '0'), this.Font, int.MaxValue, StringFormat.GenericTypographic));
            this.dateBody.month_size = (!this.IsContainDateEmbody(DateEmbody.Month)) ? Size.Empty : Size.Ceiling(g.MeasureString(this.dateBody.month_str.Replace(" ", "").PadLeft(2, '0'), this.Font, int.MaxValue, StringFormat.GenericTypographic));
            this.dateBody.month_unit_size = Size.Ceiling(TextRenderer.MeasureText(g, this.dateBody.month_unit_str.Replace(' ', '0'), this.Font));
            this.dateBody.monthday_size = Size.Ceiling(g.MeasureString(this.dateBody.monthday_str.Replace(' ', '0'), this.Font, int.MaxValue, StringFormat.GenericTypographic));
            this.dateBody.day_size = (!this.IsContainDateEmbody(DateEmbody.Day)) ? Size.Empty : Size.Ceiling(g.MeasureString(this.dateBody.day_str.Replace(" ", "").PadLeft(2, '0'), this.Font, int.MaxValue, StringFormat.GenericTypographic));
            this.dateBody.day_unit_size = Size.Ceiling(TextRenderer.MeasureText(g, this.dateBody.day_unit_str.Replace(' ', '0'), this.Font));
            this.dateBody.dayhour_size = Size.Ceiling(g.MeasureString(this.dateBody.dayhour_str.Replace(' ', '0'), this.Font, int.MaxValue, StringFormat.GenericTypographic));
            this.dateBody.hour_size = (!this.IsContainDateEmbody(DateEmbody.Hour)) ? Size.Empty : Size.Ceiling(g.MeasureString(this.dateBody.hour_str.Replace(" ", "").PadLeft(2, '0'), this.Font, int.MaxValue, StringFormat.GenericTypographic));
            this.dateBody.hour_unit_size = Size.Ceiling(TextRenderer.MeasureText(g, this.dateBody.hour_unit_str.Replace(' ', '0'), this.Font));
            this.dateBody.hourminute_size = Size.Ceiling(g.MeasureString(this.dateBody.hourminute_str.Replace(' ', '0'), this.Font, int.MaxValue, StringFormat.GenericTypographic));
            this.dateBody.minute_size = (!this.IsContainDateEmbody(DateEmbody.Minute)) ? Size.Empty : Size.Ceiling(g.MeasureString(this.dateBody.minute_str.Replace(" ", "").PadLeft(2, '0'), this.Font, int.MaxValue, StringFormat.GenericTypographic));
            this.dateBody.minute_unit_size = Size.Ceiling(TextRenderer.MeasureText(g, this.dateBody.minute_unit_str.Replace(' ', '0'), this.Font));
            this.dateBody.minutesecond_size = Size.Ceiling(g.MeasureString(this.dateBody.minutesecond_str.Replace(' ', '0'), this.Font, int.MaxValue, StringFormat.GenericTypographic));
            this.dateBody.second_size = (!this.IsContainDateEmbody(DateEmbody.Second)) ? Size.Empty : Size.Ceiling(g.MeasureString(this.dateBody.second_str.Replace(" ", "").PadLeft(2, '0'), this.Font, int.MaxValue, StringFormat.GenericTypographic));
            this.dateBody.second_unit_size = Size.Ceiling(TextRenderer.MeasureText(g, this.dateBody.second_unit_str.Replace(' ', '0'), this.Font));
            this.dateBody.secondweek_size = Size.Ceiling(g.MeasureString(this.dateBody.secondweek_str.Replace(' ', '0'), this.Font, int.MaxValue, StringFormat.GenericTypographic));
            this.dateBody.week_size = (!this.IsContainDateEmbody(DateEmbody.Week)) ? Size.Empty : Size.Ceiling(TextRenderer.MeasureText(g, this.dateBody.week_str.Replace(' ', '0'), this.Font));

            g.Dispose();
            NativeMethods.ReleaseDC(this.Handle, hDC);

            this.InitializeElement();
            this.Invalidate();
        }

        /// <summary>
        /// 更新DatePicker源时间到控件文本上
        /// </summary>
        private void SetDatePickerDateValueToText()
        {
            if (this.DatePicker.DateValue == null)
            {
                this.dateBody.year_str = "";
                this.dateBody.month_str = "";
                this.dateBody.day_str = "";
                this.dateBody.hour_str = "";
                this.dateBody.minute_str = "";
                this.dateBody.second_str = "";
                this.dateBody.week_str = "";
            }
            else
            {
                this.dateBody.year_str = this.DatePicker.DateValue.Value.Year.ToString().PadLeft(4, '0');
                this.dateBody.month_str = this.DatePicker.DateValue.Value.Month.ToString().PadLeft(2, '0');
                this.dateBody.day_str = this.DatePicker.DateValue.Value.Day.ToString().PadLeft(2, '0');
                this.dateBody.hour_str = this.DatePicker.DateValue.Value.Hour.ToString().PadLeft(2, '0');
                this.dateBody.minute_str = this.DatePicker.DateValue.Value.Minute.ToString().PadLeft(2, '0');
                this.dateBody.second_str = this.DatePicker.DateValue.Value.Second.ToString().PadLeft(2, '0');
                if (this.Content.WeekVisible)
                {
                    this.dateBody.week_str = this.GetWeekNameForDateTime(this.DatePicker.DateValue);
                    this.CalculationDateBodyElementSize();
                }
            }
        }

        /// <summary>
        /// 根据dateBody时间值更新日期面板DateValue 值触发值更改事件
        /// </summary>
        private void SetTextToDatePickerValue()
        {
            DateTime tmp = new DateTime(int.Parse(this.dateBody.year_str), int.Parse(this.dateBody.month_str), int.Parse(this.dateBody.day_str), int.Parse(this.dateBody.hour_str), int.Parse(this.dateBody.minute_str), int.Parse(this.dateBody.second_str));
            if (tmp != this.DatePicker.DateValue)
            {
                this.DatePicker.DateValue = tmp;
            }
            else
            {
                this.Invalidate();
            }
        }

        /// <summary>
        /// 键盘数字键修改dateBody时间文本值
        /// </summary>
        /// <param name="number">键盘数字</param>
        private void UpdateDateBodyValueByKeyboard(int number)
        {
            if (this.dateBody.selectElementItem == DateContentSelectedTypes.Year)
            {
                if (this.dateBody.year_str.Length == 4)
                {
                    this.dateBody.year_str = number.ToString();
                }
                else if (this.dateBody.year_str.Length < 4)
                {
                    int tmp = int.Parse(this.dateBody.year_str + number.ToString());
                    if (1 > tmp || tmp > 9999)
                    {
                        this.dateBody.year_str = this.DatePicker.DateValue.Value.Year.ToString();
                    }
                    else
                    {
                        this.dateBody.year_str = this.dateBody.year_str + number.ToString();
                    }
                }
                if (this.dateBody.year_str.Length != 4)
                {
                    this.Invalidate();
                    return;
                }
                int year = int.Parse(this.dateBody.year_str);
                if (year < this.DatePicker.MinValue.Year)
                {
                    this.dateBody.year_str = this.DatePicker.MinValue.Year.ToString();
                }
                if (year > this.DatePicker.MaxValue.Year)
                {
                    this.dateBody.year_str = this.DatePicker.MaxValue.Year.ToString();
                }

                year = int.Parse(this.dateBody.year_str);
                int month = int.Parse(this.dateBody.month_str);
                int ym_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0'));
                int ym_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMM"));
                int ym_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMM"));
                if (ym_now_int > ym_max_int)
                {
                    this.dateBody.month_str = DatePicker.MaxValue.Month.ToString();
                }
                if (ym_now_int < ym_min_int)
                {
                    this.dateBody.month_str = DatePicker.MinValue.Month.ToString();
                }


                month = int.Parse(this.dateBody.month_str);
                int days = DateTime.DaysInMonth(year, month);
                int day = int.Parse(this.dateBody.day_str);
                day = Math.Min(day, days);
                int ymd_day_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0') + day.ToString().PadLeft(2, '0'));
                int ymd_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMMdd"));
                int ymd_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMMdd"));
                if (ymd_day_int > ymd_max_int)
                {
                    day = this.DatePicker.MaxValue.Day;
                }
                if (ymd_day_int < ymd_min_int)
                {
                    day = this.DatePicker.MinValue.Day;
                }
                this.dateBody.day_str = day.ToString();

                this.SetTextToDatePickerValue();
            }
            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Month)
            {
                if (this.dateBody.month_str.Length == 2)
                {
                    this.dateBody.month_str = number.ToString();
                }
                else if (this.dateBody.month_str.Length == 1)
                {
                    int tmp = int.Parse(this.dateBody.month_str + number.ToString());
                    if (1 > tmp || tmp > 12)
                    {
                        this.dateBody.month_str = number.ToString();
                    }
                    else
                    {
                        this.dateBody.month_str = this.dateBody.month_str + number.ToString();
                    }
                }
                if (this.dateBody.month_str.Length != 2)
                {
                    this.Invalidate();
                    return;
                }
                int year = int.Parse(this.dateBody.year_str);
                int month = int.Parse(this.dateBody.month_str);
                int ym_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0'));
                int ym_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMM"));
                int ym_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMM"));

                if (ym_min_int > ym_now_int || ym_now_int > ym_max_int)
                {
                    this.dateBody.month_str = this.DatePicker.DateValue.Value.Month.ToString();
                    this.Invalidate();
                    return;
                }

                month = int.Parse(this.dateBody.month_str);
                int days = DateTime.DaysInMonth(year, month);
                int day = int.Parse(this.dateBody.day_str);
                day = Math.Min(day, days);
                int ymd_day_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0') + day.ToString().PadLeft(2, '0'));
                int ymd_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMMdd"));
                int ymd_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMMdd"));
                if (ymd_day_int > ymd_max_int)
                {
                    day = this.DatePicker.MaxValue.Day;
                }
                if (ymd_day_int < ymd_min_int)
                {
                    day = this.DatePicker.MinValue.Day;
                }
                this.dateBody.day_str = day.ToString();

                this.SetTextToDatePickerValue();
            }
            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Day)
            {
                int year = int.Parse(this.dateBody.year_str);
                int month = int.Parse(this.dateBody.month_str);
                int days = DateTime.DaysInMonth(year, month);

                if (this.dateBody.day_str.Length == 2)
                {
                    this.dateBody.day_str = number.ToString();
                }
                else if (this.dateBody.day_str.Length == 1)
                {
                    int tmp = int.Parse(this.dateBody.day_str + number.ToString());
                    if (1 > tmp || tmp > days)
                    {
                        this.dateBody.day_str = number.ToString();
                    }
                    else
                    {
                        this.dateBody.day_str = this.dateBody.day_str + number.ToString();
                    }
                }

                if (this.dateBody.day_str.Length != 2)
                {
                    this.Invalidate();
                    return;
                }

                int day = int.Parse(this.dateBody.day_str);
                int ymd_day_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0') + day.ToString().PadLeft(2, '0'));
                int ymd_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMMdd"));
                int ymd_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMMdd"));
                if (1 > day || day > days || ymd_day_int < ymd_min_int || ymd_day_int > ymd_max_int)
                {
                    this.dateBody.day_str = this.DatePicker.DateValue.Value.Day.ToString();
                    this.Invalidate();
                    return;
                }

                this.SetTextToDatePickerValue();
            }
            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Hour)
            {
                if (this.dateBody.hour_str.Length == 2)
                {
                    this.dateBody.hour_str = number.ToString();
                }
                else if (this.dateBody.hour_str.Length == 1)
                {
                    this.dateBody.hour_str = this.dateBody.hour_str + number.ToString();
                }

                if (this.dateBody.hour_str.Length != 2)
                {
                    this.Invalidate();
                    return;
                }
                int tmp = int.Parse(this.dateBody.hour_str);
                if (0 > tmp || tmp > 23)
                {
                    this.dateBody.hour_str = number.ToString();
                    this.Invalidate();
                    return;
                }

                this.SetTextToDatePickerValue();
            }
            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Minute)
            {
                if (this.dateBody.minute_str.Length == 2)
                {
                    this.dateBody.minute_str = number.ToString();
                }
                else if (this.dateBody.minute_str.Length == 1)
                {
                    this.dateBody.minute_str = this.dateBody.minute_str + number.ToString();
                }

                if (this.dateBody.minute_str.Length != 2)
                {
                    this.Invalidate();
                    return;
                }
                int tmp = int.Parse(this.dateBody.minute_str);
                if (0 > tmp || tmp > 59)
                {
                    this.dateBody.minute_str = number.ToString();
                    this.Invalidate();
                    return;
                }

                this.SetTextToDatePickerValue();
            }
            else if (this.dateBody.selectElementItem == DateContentSelectedTypes.Second)
            {
                if (this.dateBody.second_str.Length == 2)
                {
                    this.dateBody.second_str = number.ToString();
                }
                else if (this.dateBody.second_str.Length == 1)
                {
                    this.dateBody.second_str = this.dateBody.second_str + number.ToString();
                }

                if (this.dateBody.second_str.Length != 2)
                {
                    this.Invalidate();
                    return;
                }
                int tmp = int.Parse(this.dateBody.second_str);
                if (0 > tmp || tmp > 59)
                {
                    this.dateBody.second_str = number.ToString();
                    this.Invalidate();
                    return;
                }

                this.SetTextToDatePickerValue();
            }
        }

        /// <summary>
        /// 文本由选中高亮到取消选中时验证时间
        /// </summary>
        /// <param name="type">时间文本选中高亮部分</param>
        private void VaildUnSelectedValue(DateContentSelectedTypes type)
        {
            switch (type)
            {
                case DateContentSelectedTypes.Year:
                    {
                        if (this.dateBody.year_str.Length == 2)
                        {
                            this.dateBody.year_str = DateTime.Now.Year.ToString().Substring(0, 2) + this.dateBody.year_str;
                        }

                        int year = int.Parse(this.dateBody.year_str);
                        if (this.DatePicker.MinValue.Year > year || year > this.DatePicker.MaxValue.Year)
                        {
                            this.dateBody.year_str = this.DatePicker.DateValue.Value.Year.ToString().PadLeft(4, '0');
                        }

                        year = int.Parse(this.dateBody.year_str);
                        int month = int.Parse(this.dateBody.month_str);
                        int ym_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0'));
                        int ym_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMM"));
                        int ym_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMM"));
                        if (ym_now_int > ym_max_int)
                        {
                            this.dateBody.month_str = DatePicker.MaxValue.Month.ToString().PadLeft(2, '0');
                        }
                        if (ym_now_int < ym_min_int)
                        {
                            this.dateBody.month_str = DatePicker.MinValue.Month.ToString().PadLeft(2, '0');
                        }


                        month = int.Parse(this.dateBody.month_str);
                        int days = DateTime.DaysInMonth(year, month);
                        int day = int.Parse(this.dateBody.day_str);
                        day = Math.Min(day, days);
                        int ymd_day_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0') + day.ToString().PadLeft(2, '0'));
                        int ymd_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMMdd"));
                        int ymd_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMMdd"));
                        if (ymd_day_int > ymd_max_int)
                        {
                            day = this.DatePicker.MaxValue.Day;
                        }
                        if (ymd_day_int < ymd_min_int)
                        {
                            day = this.DatePicker.MinValue.Day;
                        }
                        this.dateBody.day_str = day.ToString().PadLeft(2, '0');


                        this.SetTextToDatePickerValue();

                        break;
                    }
                case DateContentSelectedTypes.Month:
                    {
                        int year = int.Parse(this.dateBody.year_str);
                        int month = int.Parse(this.dateBody.month_str);
                        int ym_now_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0'));
                        int ym_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMM"));
                        int ym_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMM"));

                        if (ym_now_int > ym_max_int || ym_now_int < ym_min_int)
                        {
                            this.dateBody.month_str = this.DatePicker.DateValue.Value.Month.ToString().PadLeft(2, '0');
                        }

                        month = int.Parse(this.dateBody.month_str);
                        int days = DateTime.DaysInMonth(year, month);
                        int day = int.Parse(this.dateBody.day_str);
                        day = Math.Min(day, days);
                        int ymd_day_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0') + day.ToString().PadLeft(2, '0'));
                        int ymd_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMMdd"));
                        int ymd_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMMdd"));
                        if (ymd_day_int > ymd_max_int)
                        {
                            day = this.DatePicker.MaxValue.Day;
                        }
                        if (ymd_day_int < ymd_min_int)
                        {
                            day = this.DatePicker.MinValue.Day;
                        }
                        this.dateBody.day_str = day.ToString().PadLeft(2, '0');


                        this.SetTextToDatePickerValue();
                        break;
                    }
                case DateContentSelectedTypes.Day:
                    {
                        int year = int.Parse(this.dateBody.year_str);
                        int month = int.Parse(this.dateBody.month_str);
                        int days = DateTime.DaysInMonth(year, month);
                        int day = int.Parse(this.dateBody.day_str);
                        int ymd_day_int = int.Parse("10" + year.ToString().PadLeft(4, '0') + month.ToString().PadLeft(2, '0') + day.ToString().PadLeft(2, '0'));
                        int ymd_max_int = int.Parse(this.DatePicker.MaxValue.ToString("10yyyyMMdd"));
                        int ymd_min_int = int.Parse(this.DatePicker.MinValue.ToString("10yyyyMMdd"));
                        if (1 > day || day > days || ymd_day_int < ymd_min_int || ymd_day_int > ymd_max_int)
                        {
                            this.dateBody.day_str = this.DatePicker.DateValue.Value.Day.ToString().PadLeft(2, '0');
                        }

                        this.SetTextToDatePickerValue();
                        break;
                    }
                case DateContentSelectedTypes.Hour:
                    {
                        int hour = int.Parse(this.dateBody.hour_str);
                        if (0 > hour || hour > 23)
                        {
                            this.dateBody.hour_str = this.DatePicker.DateValue.Value.Hour.ToString().PadLeft(2, '0');
                        }
                        if (this.dateBody.hour_str.Length == 1)
                        {
                            this.dateBody.hour_str = this.dateBody.hour_str.PadLeft(2, '0');
                        }

                        this.SetTextToDatePickerValue();
                        break;
                    }
                case DateContentSelectedTypes.Minute:
                    {
                        int minute = int.Parse(this.dateBody.minute_str);
                        if (0 > minute || minute > 59)
                        {
                            this.dateBody.minute_str = this.DatePicker.DateValue.Value.Minute.ToString().PadLeft(2, '0');
                        }
                        if (this.dateBody.minute_str.Length == 1)
                        {
                            this.dateBody.minute_str = this.dateBody.minute_str.PadLeft(2, '0');
                        }

                        this.SetTextToDatePickerValue();
                        break;
                    }
                case DateContentSelectedTypes.Second:
                    {
                        int second = int.Parse(this.dateBody.second_str);
                        if (0 > second || second > 59)
                        {
                            this.dateBody.second_str = this.DatePicker.DateValue.Value.Second.ToString().PadLeft(2, '0');
                        }
                        if (this.dateBody.second_str.Length == 1)
                        {
                            this.dateBody.second_str = this.dateBody.second_str.PadLeft(2, '0');
                        }

                        this.SetTextToDatePickerValue();
                        break;
                    }
            }
        }

        /// <summary>
        /// 更新日期控件内容允许选中的元素
        /// </summary>
        private void UpdateDateBodyElements()
        {
            List<DateContentSelectedTypes> tmp_start = new List<DateContentSelectedTypes>();
            List<DateContentSelectedTypes> itemList_tmp = new List<DateContentSelectedTypes>();
            List<DateContentSelectedTypes> tmp_end = new List<DateContentSelectedTypes>();
            if (this.Icon.Alignment == DateInputImageAlignment.Left)
            {
                tmp_start.Add(DateContentSelectedTypes.Image);
                if (this.ClearButton.Visible)
                {
                    if (this.ClearButton.Alignment == DateInputClearAlignment.Near)
                    {
                        tmp_start.Add(DateContentSelectedTypes.ClearButton);
                    }
                    else
                    {
                        tmp_end.Add(DateContentSelectedTypes.ClearButton);
                    }
                }
            }
            else
            {
                if (this.ClearButton.Visible)
                {
                    if (this.ClearButton.Alignment == DateInputClearAlignment.Near)
                    {
                        tmp_end.Add(DateContentSelectedTypes.ClearButton);
                        tmp_end.Add(DateContentSelectedTypes.Image);
                    }
                    else
                    {
                        tmp_start.Add(DateContentSelectedTypes.ClearButton);
                        tmp_end.Add(DateContentSelectedTypes.Image);
                    }
                }
                else
                {
                    tmp_end.Add(DateContentSelectedTypes.Image);
                }
            }

            foreach (DateContentSelectedTypes item in tmp_start)
            {
                itemList_tmp.Add(item);
            }
            if (this.IsContainDateEmbody(DateEmbody.Year))
            {
                itemList_tmp.Add(DateContentSelectedTypes.Year);
            }
            if (this.IsContainDateEmbody(DateEmbody.Month))
            {
                itemList_tmp.Add(DateContentSelectedTypes.Month);
            }
            if (this.IsContainDateEmbody(DateEmbody.Day))
            {
                itemList_tmp.Add(DateContentSelectedTypes.Day);
            }
            if (this.IsContainDateEmbody(DateEmbody.Hour))
            {
                itemList_tmp.Add(DateContentSelectedTypes.Hour);
            }
            if (this.IsContainDateEmbody(DateEmbody.Minute))
            {
                itemList_tmp.Add(DateContentSelectedTypes.Minute);
            }
            if (this.IsContainDateEmbody(DateEmbody.Second))
            {
                itemList_tmp.Add(DateContentSelectedTypes.Second);
            }
            foreach (DateContentSelectedTypes item in tmp_end)
            {
                itemList_tmp.Add(item);
            }

            this.dateBodyElements = itemList_tmp;
        }

        /// <summary>
        /// 是否显示是否日期指定部分
        /// </summary>
        /// <param name="dateEmbody">日期指定部分</param>
        /// <returns></returns>
        private bool IsContainDateEmbody(DateEmbody dateEmbody)
        {
            switch (dateEmbody)
            {
                case DateEmbody.Year:
                    {
                        return (this.DatePicker.DateFormat == DatePickerFormats.yyyy || this.DatePicker.DateFormat == DatePickerFormats.yyyyMM || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMdd || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHH || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHHmm || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHHmmss);
                    }
                case DateEmbody.Month:
                    {
                        return (this.DatePicker.DateFormat == DatePickerFormats.yyyyMM || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMdd || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHH || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHHmm || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHHmmss);
                    }
                case DateEmbody.Day:
                    {
                        return (this.DatePicker.DateFormat == DatePickerFormats.yyyyMMdd || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHH || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHHmm || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHHmmss);
                    }
                case DateEmbody.Hour:
                    {
                        return (this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHH || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHHmm || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHHmmss);
                    }
                case DateEmbody.Minute:
                    {
                        return (this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHHmm || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHHmmss);
                    }
                case DateEmbody.Second:
                    {
                        return (this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHHmmss);
                    }
                case DateEmbody.Week:
                    {
                        return (this.DatePicker.DateFormat == DatePickerFormats.yyyyMMdd || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHH || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHHmm || this.DatePicker.DateFormat == DatePickerFormats.yyyyMMddHHmmss) && this.Content.WeekVisible;
                    }
                default:
                    {
                        return false;
                    }
            }
        }

        /// <summary>
        /// 获取指定日期所属星期文本 
        /// </summary>
        /// <param name="date">指定日期</param>
        /// <returns></returns>
        private string GetWeekNameForDateTime(DateTime? date)
        {
            if (date == null)
            {
                return "";
            }
            else if (date.Value.DayOfWeek == DayOfWeek.Monday)
            {
                return "星期一";
            }
            else if (date.Value.DayOfWeek == DayOfWeek.Tuesday)
            {
                return "星期二";
            }
            else if (date.Value.DayOfWeek == DayOfWeek.Wednesday)
            {
                return "星期三";
            }
            else if (date.Value.DayOfWeek == DayOfWeek.Thursday)
            {
                return "星期四";
            }
            else if (date.Value.DayOfWeek == DayOfWeek.Friday)
            {
                return "星期五";
            }
            else if (date.Value.DayOfWeek == DayOfWeek.Saturday)
            {
                return "星期六";
            }
            else
            {
                return "星期日";
            }
        }

        /// <summary>
        /// 根据字体计算控件高度
        /// </summary>
        /// <returns></returns>
        private int GetControlAutoHeight()
        {
            NativeMethods.TEXTMETRIC font_metrics = ControlHelper.GetFontMetrics(this.Handle, this.Font);
            int scale_contentPadding = (int)Math.Ceiling(this.Content.Padding * this.ScaleDpi);
            int scale_height = font_metrics.GetFontRealHeight() + this.borderThickness * 2 + scale_contentPadding * 2;
            return scale_height;
        }

        #region 日期面板

        /// <summary>
        /// 隐藏日期面板弹层事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsdd_Closed(object sender, ToolStripDropDownClosedEventArgs e)
        {
            this.datePickerDisplayStatus = false;
            this.Invalidate();
            this.Select();
        }

        /// <summary>
        /// 日期面板清除事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void datePicker_BottomBarClearClick(object sender, EventArgs e)
        {
            this.tsdd.Close();
        }

        /// <summary>
        /// 日期面板现在时间事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DatePicker_BottomBarNowClick(object sender, EventArgs e)
        {
            this.tsdd.Close();
        }

        /// <summary>
        /// 日期面板确定事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void datePicker_BottomBarConfirmClick(object sender, EventArgs e)
        {
            this.tsdd.Close();
        }

        /// <summary>
        /// 日期面板时间值更改事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DatePicker_DateValueChanged(object sender, EventArgs e)
        {
            if (!this.Enabled || this.ReadOnly)
            {
                this.dateBody.selectElementItem = DateContentSelectedTypes.None;
            }
            else
            {
                if (!this.DatePicker.DateValue.HasValue)
                {
                    if (this.dateBody.selectElementItem != DateContentSelectedTypes.None)
                    {
                        this.dateBody.selectElementItem = DateContentSelectedTypes.Image;
                    }
                    else
                    {
                        this.dateBody.selectElementItem = DateContentSelectedTypes.None;
                    }
                    this.UpdateDateBodyElements();
                }
            }
            this.SetDatePickerDateValueToText();
            this.InitializeElement();
            this.Invalidate();
        }

        /// <summary>
        /// 日期面板日期格式更改事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DatePicker_DateFormatChanged(object sender, EventArgs e)
        {
            this.SetDatePickerDateValueToText();
            this.dateBody.selectElementItem = DateContentSelectedTypes.None;
            this.UpdateDateBodyElements();
            this.UpdateDateSymbol();
        }

        /// <summary>
        /// 显示日期面板
        /// </summary>
        private void ShowDatePicker()
        {
            if (!this.datePickerDisplayStatus)
            {
                if (this.tsdd == null)
                {
                    this.tsdd = new ToolStripDropDown() { Padding = System.Windows.Forms.Padding.Empty };
                    this.tsdd.Closed += this.tsdd_Closed;
                }
                if (this.tsch == null)
                {
                    this.tsch = new ToolStripControlHost(this.DatePicker) { Margin = System.Windows.Forms.Padding.Empty, Padding = System.Windows.Forms.Padding.Empty };
                    this.tsch.Size = this.DatePicker.Size;
                    tsdd.Items.Add(this.tsch);
                }

                Rectangle screen_rect = Screen.FromControl(this).WorkingArea;
                Point screen_control_point = this.PointToScreen(new Point(((this.Icon.Alignment == DateInputImageAlignment.Left) ? 0 : (this.ClientRectangle.Right - this.DatePicker.Size.Width)), this.Height + 2));
                if (screen_control_point.Y + this.DatePicker.Size.Height > screen_rect.Bottom)
                {
                    screen_control_point = new Point(screen_control_point.X, screen_control_point.Y - this.Height - 6 - this.DatePicker.Size.Height);
                }
                tsdd.Show(screen_control_point);
                this.DatePicker.InitializeViewForDateValue();
            }
        }

        #endregion

        #endregion

        #region 枚举

        /// <summary>
        /// 当前日期文本显示包含指定部分
        /// </summary>
        internal enum DateEmbody
        {
            /// <summary>
            /// 年
            /// </summary>
            Year,
            /// <summary>
            /// 月
            /// </summary>
            Month,
            /// <summary>
            /// 日
            /// </summary>
            Day,
            /// <summary>
            /// 时
            /// </summary>
            Hour,
            /// <summary>
            /// 分
            /// </summary>
            Minute,
            /// <summary>
            /// 秒
            /// </summary>
            Second,
            /// <summary>
            /// 星期
            /// </summary>
            Week
        }

        /// <summary>
        /// 日期控件内容允许选中的元素
        /// </summary>
        internal enum DateContentSelectedTypes
        {
            /// <summary>
            /// 没选中
            /// </summary>
            None,
            /// <summary>
            /// 图标
            /// </summary>
            Image,
            /// <summary>
            /// 清除按钮
            /// </summary>
            ClearButton,
            /// <summary>
            /// 年
            /// </summary>
            Year,
            /// <summary>
            /// 月
            /// </summary>
            Month,
            /// <summary>
            /// 日
            /// </summary>
            Day,
            /// <summary>
            /// 时
            /// </summary>
            Hour,
            /// <summary>
            /// 分
            /// </summary>
            Minute,
            /// <summary>
            /// 秒
            /// </summary>
            Second
        }

        /// <summary>
        ///当前鼠标按下的功能区
        /// </summary>
        internal enum MouseDownAreaTypes
        {
            /// <summary>
            /// 没有
            /// </summary>
            None,
            /// <summary>
            /// 整个控件
            /// </summary>
            Main,
            /// <summary>
            /// 图片
            /// </summary>
            Image,
            /// <summary>
            /// 清除按钮
            /// </summary>
            ClearButton,
            /// <summary>
            /// 日期文本
            /// </summary>
            DateText
        }

        #endregion

        #region 类

        [TypeConverter(typeof(PropertyOrderConverter))]
        public class ContentObject
        {
            private DateInput owner = null;
            internal ContentObject(DateInput owner) { this.owner = owner; }

            #region 属性

            private int padding = 3;
            /// <summary>
            /// 边框与内容的距离
            /// </summary>
            [Description("边框与内容的距离")]
            [Category("杂项")]
            [PropertyOrder(-193)]
            [DefaultValue(3)]
            public int Padding
            {
                get { return this.padding; }
                set
                {
                    if (this.padding == value)
                        return;

                    this.padding = value;
                    ((DateInput)this.owner).Height = ((DateInput)this.owner).GetControlAutoHeight();
                    if (this.owner != null)
                    {
                        this.owner.InitializeElement();
                        this.owner.Invalidate();
                    }
                }
            }

            private DateInputTextAlignment textAlignment = DateInputTextAlignment.Left;
            /// <summary>
            /// 日期文本对齐方式
            /// </summary>
            [Description("日期文本对齐方式")]
            [PropertyOrder(-188)]
            [DefaultValue(DateInputTextAlignment.Left)]
            public DateInputTextAlignment TextAlignment
            {
                get { return this.textAlignment; }
                set
                {
                    if (this.textAlignment == value)
                        return;

                    this.textAlignment = value;
                    if (this.owner != null)
                    {
                        this.owner.InitializeElement();
                        this.owner.Invalidate();
                    }
                }
            }

            private bool weekVisible = false;
            /// <summary>
            /// 是否显示星期
            /// </summary>
            [Description("是否显示星期")]
            [PropertyOrder(-186)]
            [DefaultValue(false)]
            public bool WeekVisible
            {
                get { return this.weekVisible; }
                set
                {
                    if (this.weekVisible == value)
                        return;

                    this.weekVisible = value;
                    ((DateInput)this.owner).UpdateDateSymbol();
                }
            }

            private DateInputSymbolPattern symbolPattern = DateInputSymbolPattern.CrossLine;
            /// <summary>
            /// 日期分隔符风格模式
            /// </summary>
            [Description("日期分隔符风格模式")]
            [PropertyOrder(-184)]
            [DefaultValue(DateInputSymbolPattern.CrossLine)]
            public DateInputSymbolPattern SymbolPattern
            {
                get { return this.symbolPattern; }
                set
                {
                    if (this.symbolPattern == value)
                        return;

                    this.symbolPattern = value;
                    ((DateInput)this.owner).UpdateDateSymbol();
                }
            }

            private string nullTipText = "";
            /// <summary>
            /// 日期空值提示文本
            /// </summary>
            [Description("日期空值提示文本")]
            [PropertyOrder(-182)]
            [DefaultValue("")]
            public string NullTipText
            {
                get { return this.nullTipText; }
                set
                {
                    if (this.nullTipText == value)
                        return;

                    this.nullTipText = value;
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            #endregion

        }

        [TypeConverter(typeof(PropertyOrderConverter))]
        public class ClearButtonObject
        {
            private DateInput owner = null;
            internal ClearButtonObject(DateInput owner) { this.owner = owner; }

            #region 属性

            private bool visible = false;
            /// <summary>
            /// 是否显示清除按钮
            /// </summary>
            [Description("是否显示清除按钮")]
            [PropertyOrder(-198)]
            [DefaultValue(false)]
            public bool Visible
            {
                get { return this.visible; }
                set
                {
                    if (this.visible == value)
                        return;

                    this.visible = value;
                    ((DateInput)this.owner).UpdateDateBodyElements();
                    if (this.owner != null)
                    {
                        this.owner.InitializeElement();
                        this.owner.Invalidate();
                    }
                }
            }

            private DateInputClearAlignment alignment = DateInputClearAlignment.Far;
            /// <summary>
            /// 清除按钮对齐方式（相对于DateImage）
            /// </summary>
            [Description("清除按钮对齐方式（相对于DateImage）")]
            [PropertyOrder(-196)]
            [DefaultValue(DateInputClearAlignment.Far)]
            public DateInputClearAlignment Alignment
            {
                get { return this.alignment; }
                set
                {
                    if (this.alignment == value)
                        return;

                    this.alignment = value;
                    ((DateInput)this.owner).UpdateDateBodyElements();
                    if (this.owner != null)
                    {
                        this.owner.InitializeElement();
                        this.owner.Invalidate();
                    }
                }
            }

            #endregion

        }

        [TypeConverter(typeof(PropertyOrderConverter))]
        public class IconObject
        {
            private DateInput owner = null;
            internal IconObject(DateInput owner) { this.owner = owner; }

            #region 属性

            private DateInputImageAlignment alignment = DateInputImageAlignment.Left;
            /// <summary>
            /// 图标对齐方式
            /// </summary>
            [Description("图标对齐方式")]
            [PropertyOrder(-198)]
            [DefaultValue(DateInputImageAlignment.Left)]
            public DateInputImageAlignment Alignment
            {
                get { return this.alignment; }
                set
                {
                    if (this.alignment == value)
                        return;

                    this.alignment = value;
                    ((DateInput)this.owner).UpdateDateBodyElements();
                    if (this.owner != null)
                    {
                        this.owner.InitializeElement();
                        this.owner.Invalidate();
                    }
                }
            }

            private Image image = null;
            /// <summary>
            /// 图标
            /// </summary>
            [Description("图标")]
            [PropertyOrder(-190)]
            [DefaultValue(null)]
            [RefreshProperties(RefreshProperties.Repaint)]
            public Image Image
            {
                get { return this.image; }
                set
                {
                    if (this.image == value)
                        return;

                    this.image = value;
                    if (((DateInput)this.owner).disable_image_tmp != null)
                    {
                        ((DateInput)this.owner).disable_image_tmp.Dispose();
                        ((DateInput)this.owner).disable_image_tmp = null;
                    }

                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            #endregion

        }

        /// <summary>
        /// 存放时间元素信息
        /// </summary>
        internal class DateBodyClass
        {
            /// <summary>
            /// 日期控件内容选中类型索引
            /// </summary>
            public DateContentSelectedTypes selectElementItem = DateContentSelectedTypes.None;

            /// <summary>
            /// 内容Rect
            /// </summary>
            public Rectangle content_rect = Rectangle.Empty;

            /// <summary>
            /// 图片Rect
            /// </summary>
            public Rectangle image_rect = Rectangle.Empty;

            /// <summary>
            /// 清除按钮Rect
            /// </summary>
            public Rectangle clear_btn_rect = Rectangle.Empty;

            /// <summary>
            /// 时间值Rect
            /// </summary>
            public Rectangle value_rect = Rectangle.Empty;



            /// <summary>
            /// 年文本
            /// </summary>
            public string year_str = "    ";
            /// <summary>
            /// 年文本Size
            /// </summary>
            public Size year_size = Size.Empty;
            /// <summary>
            /// 年文本Rect
            /// </summary>
            public Rectangle year_rect = Rectangle.Empty;


            /// <summary>
            /// 年单位文本
            /// </summary>
            public string year_unit_str = "";
            /// <summary>
            /// 年单位文本Size
            /// </summary>
            public Size year_unit_size = Size.Empty;
            /// <summary>
            /// 年单位文本Rect
            /// </summary>
            public Rectangle year_unit_rect = Rectangle.Empty;


            /// <summary>
            /// 年月分隔符文本
            /// </summary>
            public string yearmonth_str = "-";
            /// <summary>
            /// 年月分隔符文本Size
            /// </summary>
            public Size yearmonth_size = Size.Empty;
            /// <summary>
            /// 年月分隔符文本Rect
            /// </summary>
            public Rectangle yearmonth_rect = Rectangle.Empty;



            /// <summary>
            /// 月文本
            /// </summary>
            public string month_str = "  ";
            /// <summary>
            /// 月文本Size
            /// </summary>
            public Size month_size = Size.Empty;
            /// <summary>
            /// 月文本Rect
            /// </summary>
            public Rectangle month_rect = Rectangle.Empty;


            /// <summary>
            /// 月单位文本
            /// </summary>
            public string month_unit_str = "";
            /// <summary>
            /// 月单位文本Size
            /// </summary>
            public Size month_unit_size = Size.Empty;
            /// <summary>
            /// 月单位文本Rect
            /// </summary>
            public Rectangle month_unit_rect = Rectangle.Empty;



            /// <summary>
            /// 月日分隔符文本
            /// </summary>
            public string monthday_str = "-";
            /// <summary>
            /// 月日分隔符文本Size
            /// </summary>
            public Size monthday_size = Size.Empty;
            /// <summary>
            /// 月日分隔符文本Rect
            /// </summary>
            public Rectangle monthday_rect = Rectangle.Empty;



            /// <summary>
            /// 日文本
            /// </summary>
            public string day_str = "  ";
            /// <summary>
            /// 日文本Size
            /// </summary>
            public Size day_size = Size.Empty;
            /// <summary>
            /// 日文本Rect
            /// </summary>
            public Rectangle day_rect = Rectangle.Empty;



            /// <summary>
            /// 日单位文本
            /// </summary>
            public string day_unit_str = "";
            /// <summary>
            /// 日单位文本Size
            /// </summary>
            public Size day_unit_size = Size.Empty;
            /// <summary>
            /// 日单位文本Rect
            /// </summary>
            public Rectangle day_unit_rect = Rectangle.Empty;



            /// <summary>
            /// 日时分隔符文本
            /// </summary>
            public string dayhour_str = "";
            /// <summary>
            /// 日时分隔符文本Size
            /// </summary>
            public Size dayhour_size = Size.Empty;
            /// <summary>
            /// 日时分隔符文本Rect
            /// </summary>
            public Rectangle dayhour_rect = Rectangle.Empty;


            /// <summary>
            /// 时文本
            /// </summary>
            public string hour_str = "  ";
            /// <summary>
            /// 时文本Size
            /// </summary>
            public Size hour_size = Size.Empty;
            /// <summary>
            /// 时文本Rect
            /// </summary>
            public Rectangle hour_rect = Rectangle.Empty;



            /// <summary>
            /// 时单位文本
            /// </summary>
            public string hour_unit_str = "";
            /// <summary>
            /// 时单位文本Size
            /// </summary>
            public Size hour_unit_size = Size.Empty;
            /// <summary>
            /// 时单位文本Rect
            /// </summary>
            public Rectangle hour_unit_rect = Rectangle.Empty;



            /// <summary>
            /// 时分分隔符文本
            /// </summary>
            public string hourminute_str = "";
            /// <summary>
            /// 时分分隔符文本Size
            /// </summary>
            public Size hourminute_size = Size.Empty;
            /// <summary>
            /// 时分分隔符文本Rect
            /// </summary>
            public Rectangle hourminute_rect = Rectangle.Empty;



            /// <summary>
            /// 分文本
            /// </summary>
            public string minute_str = "  ";
            /// <summary>
            /// 分文本Size
            /// </summary>
            public Size minute_size = Size.Empty;
            /// <summary>
            /// 分文本Rect
            /// </summary>
            public Rectangle minute_rect = Rectangle.Empty;



            /// <summary>
            /// 分单位文本
            /// </summary>
            public string minute_unit_str = "";
            /// <summary>
            /// 分单位文本Size
            /// </summary>
            public Size minute_unit_size = Size.Empty;
            /// <summary>
            /// 分单位文本Rect
            /// </summary>
            public Rectangle minute_unit_rect = Rectangle.Empty;



            /// <summary>
            /// 分秒分隔符文本
            /// </summary>
            public string minutesecond_str = "";
            /// <summary>
            /// 分秒分隔符文本Size
            /// </summary>
            public Size minutesecond_size = Size.Empty;
            /// <summary>
            /// 分秒分隔符文本Rect
            /// </summary>
            public Rectangle minutesecond_rect = Rectangle.Empty;


            /// <summary>
            /// 秒文本
            /// </summary>
            public string second_str = "  ";
            /// <summary>
            /// 秒文本Size
            /// </summary>
            public Size second_size = Size.Empty;
            /// <summary>
            /// 秒文本Rect
            /// </summary>
            public Rectangle second_rect = Rectangle.Empty;



            /// <summary>
            /// 秒单位文本
            /// </summary>
            public string second_unit_str = "";
            /// <summary>
            /// 秒单位文本Size
            /// </summary>
            public Size second_unit_size = Size.Empty;
            /// <summary>
            /// 秒单位文本Rect
            /// </summary>
            public Rectangle second_unit_rect = Rectangle.Empty;



            /// <summary>
            /// 秒星期分隔符文本
            /// </summary>
            public string secondweek_str = "";
            /// <summary>
            /// 秒星期分隔符文本Size
            /// </summary>
            public Size secondweek_size = Size.Empty;
            /// <summary>
            /// 秒星期分隔符文本Rect
            /// </summary>
            public Rectangle secondweek_rect = Rectangle.Empty;



            /// <summary>
            /// 星期文本
            /// </summary>
            public string week_str = "";
            /// <summary>
            /// 星期文本Size
            /// </summary>
            public Size week_size = Size.Empty;
            /// <summary>
            /// 星期文本Rect
            /// </summary>
            public Rectangle week_rect = Rectangle.Empty;


        }

        #endregion

        #region 外观

        public class StyleAppearanceObject : AppearanceObjectBase
        {
            internal StyleAppearanceObject(ISkinObject owner, AppearanceObjectBase parent) : base(owner, parent) { }

            #region 属性

            private Color skinActivateColor = Color.Empty;
            private readonly Color defaultActivateColor = SystemColors.ControlText;
            private Color activateColor = Color.Empty;
            /// <summary>
            /// 控件激活的虚线框颜色
            /// </summary>
            [Description("控件激活的虚线框颜色")]
            [PropertyOrder(-198)]
            [SkinProperty(true, false)]
            public Color ActivateColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinActivateColor;
                    }

                    if (this.activateColor != Color.Empty)
                    {
                        return this.activateColor;
                    }

                    return this.defaultActivateColor;
                }
                set
                {
                    if (this.activateColor == value)
                        return;

                    this.activateColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeActivateColor()
            {
                return this.activateColor != Color.Empty;
            }
            private void ResetActivateColor()
            {
                this.activateColor = Color.Empty;
                this.Invalidate();
            }

            private ItemAppearanceObject normal;
            /// <summary>
            /// 正常状态
            /// </summary>
            [Description("正常状态")]
            [PropertyOrder(-194)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public ItemAppearanceObject Normal
            {
                get
                {
                    if (this.normal == null)
                        this.normal = new ItemAppearanceObject(this.owner, this, SystemColors.ActiveCaption, SystemColors.Window, SystemColors.ControlText, SystemColors.ControlText, SystemColors.ControlText);
                    return this.normal;
                }
            }

            private ItemAppearanceObject disabled;
            /// <summary>
            /// 禁用状态
            /// </summary>
            [Description("禁用状态")]
            [PropertyOrder(-192)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public ItemAppearanceObject Disabled
            {
                get
                {
                    if (this.disabled == null)
                        this.disabled = new ItemAppearanceObject(this.owner, this, SystemColors.InactiveCaption, SystemColors.ButtonFace, SystemColors.GrayText, SystemColors.GrayText, SystemColors.GrayText);
                    return this.disabled;
                }
            }

            private Color skinHighlightBackColor = Color.Empty;
            private readonly Color defaultHighlightBackColor = SystemColors.Highlight;
            private Color highlightBackColor = Color.Empty;
            /// <summary>
            /// 日期文本背景颜色（高亮）
            /// </summary>
            [Description("日期文本背景颜色（高亮）")]
            [PropertyOrder(-188)]
            [SkinProperty(true, false)]
            public Color HighlightBackColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinHighlightBackColor;
                    }

                    if (this.highlightBackColor != Color.Empty)
                    {
                        return this.highlightBackColor;
                    }

                    return this.defaultHighlightBackColor;
                }
                set
                {
                    if (this.highlightBackColor == value)
                        return;

                    this.highlightBackColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeHighlightBackColor()
            {
                return this.highlightBackColor != Color.Empty;
            }
            private void ResetHighlightBackColor()
            {
                this.highlightBackColor = Color.Empty;
                this.Invalidate();
            }

            private Color skinHighlightTextColor = Color.Empty;
            private readonly Color defaultHighlightTextColor = SystemColors.HighlightText;
            private Color highlightTextColor = Color.Empty;
            /// <summary>
            /// 日期文本颜色（高亮）
            /// </summary>
            [Description("日期文本颜色（高亮）")]
            [PropertyOrder(-186)]
            [SkinProperty(true, false)]
            public Color HighlightTextColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinHighlightTextColor;
                    }

                    if (this.highlightTextColor != Color.Empty)
                    {
                        return this.highlightTextColor;
                    }

                    return this.defaultHighlightTextColor;
                }
                set
                {
                    if (this.highlightTextColor == value)
                        return;

                    this.highlightTextColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeHighlightTextColor()
            {
                return this.highlightTextColor != Color.Empty;
            }
            private void ResetHighlightTextColor()
            {
                this.highlightTextColor = Color.Empty;
                this.Invalidate();
            }

            private Color skinNullTipTextColor = Color.Empty;
            private readonly Color defaultNullTipTextColor = Color.Tomato;
            private Color nullTipTextColor = Color.Empty;
            /// <summary>
            /// 日期空值提示文本颜色
            /// </summary>
            [Description("日期空值提示文本颜色")]
            [PropertyOrder(-184)]
            [SkinProperty(true, false)]
            public Color NullTipTextColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinNullTipTextColor;
                    }

                    if (this.nullTipTextColor != Color.Empty)
                    {
                        return this.nullTipTextColor;
                    }

                    return this.defaultNullTipTextColor;
                }
                set
                {
                    if (this.nullTipTextColor == value)
                        return;

                    this.nullTipTextColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeNullTipTextColor()
            {
                return this.nullTipTextColor != Color.Empty;
            }
            private void ResetNullTipTextColor()
            {
                this.nullTipTextColor = Color.Empty;
                this.Invalidate();
            }

            private ClearButtonAppearanceObject clearButton;
            /// <summary>
            /// 清除按钮
            /// </summary>
            [Description("清除按钮")]
            [PropertyOrder(-182)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public ClearButtonAppearanceObject ClearButton
            {
                get
                {
                    if (this.clearButton == null)
                        this.clearButton = new ClearButtonAppearanceObject(this.owner, this);
                    return this.clearButton;
                }
            }

            #endregion

            public class ClearButtonAppearanceObject : AppearanceObjectBase
            {
                internal ClearButtonAppearanceObject(ISkinObject owner, AppearanceObjectBase parent) : base(owner, parent) { }

                #region 属性

                private Color skinForeColor = Color.Empty;
                private readonly Color defaultForeColor = Color.Tomato;
                private Color foreColor = Color.Empty;
                /// <summary>
                /// 清除按钮前景色
                /// </summary>
                [Description("清除按钮前景色")]
                [PropertyOrder(-96)]
                [SkinProperty(true, false)]
                public Color ForeColor
                {
                    get
                    {
                        if (this.owner.GetSkinObjectSkinStateCore())
                        {
                            return this.skinForeColor;
                        }

                        if (this.foreColor != Color.Empty)
                        {
                            return this.foreColor;
                        }

                        return this.defaultForeColor;
                    }
                    set
                    {
                        if (this.foreColor == value)
                            return;

                        this.foreColor = value;
                        this.Invalidate();
                    }
                }
                private bool ShouldSerializeForeColor()
                {
                    return this.foreColor != Color.Empty;
                }
                private void ResetForeColor()
                {
                    this.foreColor = Color.Empty;
                    this.Invalidate();
                }

                #endregion

            }

            public class ItemAppearanceObject : AppearanceObjectBase
            {
                internal ItemAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color borderColor, Color backColor, Color textColor, Color symbolColor, Color weekColor) : base(owner, parent)
                {
                    this.defaultBorderColor = borderColor;
                    this.defaultBackColor = backColor;
                    this.defaultTextColor = textColor;
                    this.defaultSymbolColor = symbolColor;
                    this.defaultWeekColor = weekColor;
                }

                #region 属性

                private Color skinBorderColor = Color.Empty;
                private readonly Color defaultBorderColor = Color.Empty;
                private Color borderColor = Color.Empty;
                /// <summary>
                /// 边框颜色
                /// </summary>
                [Description("边框颜色")]
                [PropertyOrder(-199)]
                [SkinProperty(true, false)]
                public Color BorderColor
                {
                    get
                    {
                        if (this.owner.GetSkinObjectSkinStateCore())
                        {
                            return this.skinBorderColor;
                        }

                        if (this.borderColor != Color.Empty)
                        {
                            return this.borderColor;
                        }

                        return this.defaultBorderColor;
                    }
                    set
                    {
                        if (this.borderColor == value)
                            return;

                        this.borderColor = value;
                        this.Invalidate();
                    }
                }
                private bool ShouldSerializeBorderColor()
                {
                    return this.borderColor != Color.Empty;
                }
                private void ResetBorderColor()
                {
                    this.borderColor = Color.Empty;
                    this.Invalidate();
                }

                private Color skinBackColor = Color.Empty;
                private readonly Color defaultBackColor = Color.Empty;
                private Color backColor = Color.Empty;
                /// <summary>
                /// 背景颜色
                /// </summary>
                [Description("背景颜色")]
                [PropertyOrder(-198)]
                [SkinProperty(true, false)]
                public Color BackColor
                {
                    get
                    {
                        if (this.owner.GetSkinObjectSkinStateCore())
                        {
                            return this.skinBackColor;
                        }

                        if (this.backColor != Color.Empty)
                        {
                            return this.backColor;
                        }

                        return this.defaultBackColor;
                    }
                    set
                    {
                        if (this.backColor == value)
                            return;

                        this.backColor = value;
                        this.Invalidate();
                    }
                }
                private bool ShouldSerializeBackColor()
                {
                    return this.backColor != Color.Empty;
                }
                private void ResetBackColor()
                {
                    this.backColor = Color.Empty;
                    this.Invalidate();
                }

                private Color skinTextColor = Color.Empty;
                private readonly Color defaultTextColor = Color.Empty;
                private Color textColor = Color.Empty;
                /// <summary>
                /// 文本颜色
                /// </summary>
                [Description("文本颜色")]
                [PropertyOrder(-197)]
                [SkinProperty(true, false)]
                public Color TextColor
                {
                    get
                    {
                        if (this.owner.GetSkinObjectSkinStateCore())
                        {
                            return this.skinTextColor;
                        }

                        if (this.textColor != Color.Empty)
                        {
                            return this.textColor;
                        }

                        return this.defaultTextColor;
                    }
                    set
                    {
                        if (this.textColor == value)
                            return;

                        this.textColor = value;
                        this.Invalidate();
                    }
                }
                private bool ShouldSerializeTextColor()
                {
                    return this.textColor != Color.Empty;
                }
                private void ResetTextColor()
                {
                    this.textColor = Color.Empty;
                    this.Invalidate();
                }

                private Color skinWeekColor = Color.Empty;
                private readonly Color defaultWeekColor = Color.Empty;
                private Color weekColor = Color.Empty;
                /// <summary>
                /// 星期文本颜色
                /// </summary>
                [Description("星期文本颜色")]
                [PropertyOrder(-192)]
                [SkinProperty(true, false)]
                public Color WeekColor
                {
                    get
                    {
                        if (this.owner.GetSkinObjectSkinStateCore())
                        {
                            return this.skinWeekColor;
                        }

                        if (this.weekColor != Color.Empty)
                        {
                            return this.weekColor;
                        }

                        return this.defaultWeekColor;
                    }
                    set
                    {
                        if (this.weekColor == value)
                            return;

                        this.weekColor = value;
                        this.Invalidate();
                    }
                }
                private bool ShouldSerializeWeekColor()
                {
                    return this.weekColor != Color.Empty;
                }
                private void ResetWeekColor()
                {
                    this.weekColor = Color.Empty;
                    this.Invalidate();
                }

                private Color skinSymbolColor = Color.Empty;
                private readonly Color defaultSymbolColor = Color.Empty;
                private Color symbolColor = Color.Empty;
                /// <summary>
                /// 日期符号颜色
                /// </summary>
                [Description("日期符号颜色")]
                [PropertyOrder(-190)]
                [SkinProperty(true, false)]
                public Color SymbolColor
                {
                    get
                    {
                        if (this.owner.GetSkinObjectSkinStateCore())
                        {
                            return this.skinSymbolColor;
                        }

                        if (this.symbolColor != Color.Empty)
                        {
                            return this.symbolColor;
                        }

                        return this.defaultSymbolColor;
                    }
                    set
                    {
                        if (this.symbolColor == value)
                            return;

                        this.symbolColor = value;
                        this.Invalidate();
                    }
                }
                private bool ShouldSerializeSymbolColor()
                {
                    return this.symbolColor != Color.Empty;
                }
                private void ResetSymbolColor()
                {
                    this.symbolColor = Color.Empty;
                    this.Invalidate();
                }

                #endregion

            }

        }

        #endregion

    }

}
